diff --git a/Furqan.pro b/Furqan.pro
new file mode 100644
index 0000000..6602de0
--- /dev/null
+++ b/Furqan.pro
@@ -0,0 +1,109 @@
+QT = core gui widgets sql printsupport
+
+TEMPLATE = app
+
+TARGET = Furqan
+
+VERSION = 1.0.0
+
+CONFIG += release
+
+RESOURCES += \
+ resource.qrc
+
+RC_ICONS = furqan.ico
+
+TRANSLATIONS += translations\en.ts translations\ar.ts
+
+INCLUDEPATH += widgets structures relations delegates handlers utility
+
+FORMS += \
+ interfaces\classwidget.ui \
+ interfaces\competitionwidget.ui \
+ interfaces\competitorwidget.ui \
+ interfaces\coursewidget.ui \
+ interfaces\mainwidget.ui \
+ interfaces\employeewidget.ui \
+ interfaces\jobwidget.ui \
+ interfaces\quranwidget.ui \
+ interfaces\resultwidget.ui \
+ interfaces\settingwidget.ui \
+ interfaces\studentwidget.ui \
+ interfaces\teacherwidget.ui \
+ interfaces\teachingwidget.ui
+
+HEADERS += \
+ delegates/datedelegate.h \
+ delegates/mapdelegate.h \
+ delegates/numericdelegate.h \
+ delegates/relationaldelegate.h \
+ delegates/sqldelegate.h \
+ delegates/uniquedelegate.h \
+ handlers/databasehandler.h \
+ handlers/maphandler.h \
+ handlers/modelhandler.h \
+ handlers/printerhandler.h \
+ handlers/settinghandler.h \
+ handlers/translatorhandler.h \
+ relations/abstractrelation.h \
+ relations/maprelation.h \
+ relations/sqlrelation.h \
+ structures/printOption.h \
+ structures/richsqlmodel.h \
+ utility/enumeration.h \
+ utility/generalenumeration.h \
+ utility/mapenumeration.h \
+ utility/resourcemanager.h \
+ utility/settingenumeration.h \
+ utility/sqlenumeration.h \
+ widgets/classwidget.h \
+ widgets/competitionwidget.h \
+ widgets/competitorwidget.h \
+ widgets/coursewidget.h \
+ widgets/mainwidget.h \
+ widgets/employeewidget.h \
+ widgets/jobwidget.h \
+ widgets/quranwidget.h \
+ widgets/resultwidget.h \
+ widgets/settingwidget.h \
+ widgets/studentwidget.h \
+ widgets/teacherwidget.h \
+ widgets/teachingwidget.h \
+ widgets/printdialog.h \
+ widgets/texteditor.h
+
+SOURCES += \
+ delegates/datedelegate.cpp \
+ delegates/mapdelegate.cpp \
+ delegates/numericdelegate.cpp \
+ delegates/relationaldelegate.cpp \
+ delegates/sqldelegate.cpp \
+ delegates/uniquedelegate.cpp \
+ handlers/databasehandler.cpp \
+ handlers/maphandler.cpp \
+ handlers/modelhandler.cpp \
+ handlers/printerhandler.cpp \
+ handlers/settinghandler.cpp \
+ handlers/translatorhandler.cpp \
+ relations/abstractrelation.cpp \
+ relations/maprelation.cpp \
+ relations/sqlrelation.cpp \
+ structures/printoption.cpp \
+ structures/richsqlmodel.cpp \
+ utility/resourcemanager.cpp \
+ widgets/classwidget.cpp \
+ widgets/competitionwidget.cpp \
+ widgets/competitorwidget.cpp \
+ widgets/coursewidget.cpp \
+ widgets/mainwidget.cpp \
+ widgets/employeewidget.cpp \
+ widgets/jobwidget.cpp \
+ widgets/quranwidget.cpp \
+ widgets/resultwidget.cpp \
+ widgets/settingwidget.cpp \
+ widgets/studentwidget.cpp \
+ widgets/teacherwidget.cpp \
+ widgets/teachingwidget.cpp \
+ widgets/printdialog.cpp \
+ widgets/texteditor.cpp \
+ main.cpp
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..9cecc1d
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ {one line to give the program's name and a brief idea of what it does.}
+ Copyright (C) {year} {name of author}
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ {project} Copyright (C) {year} {fullname}
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1d36b4c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,18 @@
+Furqan
+======
+An institute management system written in C++/Qt. It's specialized for institutes teaching Quran-related courses.
+
+Version: 1.0.0
+
+GitHub hosts source code at:
+https://github.com/Laateef/Furqan
+
+SourceForge hosts binaries at:
+https://sourceforge.net/projects/furqan/
+
+Requirements
+------------
+* Qt Libraries: 5.x.x
+* Firbird Server (Embedded or Standalone): 2.5.x
+
+License: GPLv3
\ No newline at end of file
diff --git a/database-schema.sql b/database-schema.sql
new file mode 100644
index 0000000..1abb3aa
Binary files /dev/null and b/database-schema.sql differ
diff --git a/delegates/datedelegate.cpp b/delegates/datedelegate.cpp
new file mode 100644
index 0000000..f9806f3
--- /dev/null
+++ b/delegates/datedelegate.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "datedelegate.h"
+
+#include
+#include
+
+DateDelegate::DateDelegate(QObject *parent) :
+ QStyledItemDelegate(parent)
+{}
+
+QWidget *DateDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ Q_UNUSED(option)
+
+ QDateEdit *dateEdit = new QDateEdit(parent);
+
+ if (index.data().isNull())
+ dateEdit->setDate(QDate::currentDate());
+ else
+ dateEdit->setDate(index.data().toDate());
+
+ return dateEdit;
+}
+
+void DateDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
+{
+ QDateEdit *dateEdit = qobject_cast(editor);
+
+ if (!dateEdit)
+ return;
+
+ QAbstractItemModel *mdl = model;
+ QModelIndex idx = index;
+
+ if (model->inherits("QAbstractProxyModel")) {
+ QSortFilterProxyModel *proxyModel = qobject_cast(model);
+ if (proxyModel) {
+ mdl = proxyModel->sourceModel();
+ idx = proxyModel->mapToSource(index);
+ }
+ }
+
+ mdl->setData(idx, dateEdit->date());
+ mdl->submit();
+}
diff --git a/delegates/datedelegate.h b/delegates/datedelegate.h
new file mode 100644
index 0000000..0e112c1
--- /dev/null
+++ b/delegates/datedelegate.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef DATEDELEGATE_H
+#define DATEDELEGATE_H
+
+#include
+
+class DateDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+
+public:
+ explicit DateDelegate(QObject *parent = 0);
+
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+
+ void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
+};
+
+#endif // DATEDELEGATE_H
diff --git a/delegates/mapdelegate.cpp b/delegates/mapdelegate.cpp
new file mode 100644
index 0000000..3d5e303
--- /dev/null
+++ b/delegates/mapdelegate.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "mapdelegate.h"
+
+#include "maprelation.h"
+#include "richsqlmodel.h"
+
+#include
+#include
+
+MapDelegate::MapDelegate(QObject *parent) :
+ QStyledItemDelegate(parent)
+{}
+
+QWidget *MapDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ Q_UNUSED(option)
+
+ AbstractRelation *relation = NULL;
+
+ if (index.model()->inherits("QAbstractProxyModel")) {
+ const QSortFilterProxyModel *proxyModel = qobject_cast(index.model());
+ if (proxyModel) {
+ relation = qobject_cast(proxyModel->sourceModel())->relation(proxyModel->mapToSource(index).column());
+ }
+ } else {
+ relation = qobject_cast(index.model())->relation(index.column());
+ }
+
+ if (!relation || relation->type() != AbstractRelation::Map)
+ return NULL;
+
+ MapRelation *mapRelation = qobject_cast(relation);
+
+ QComboBox *combo = new QComboBox(parent);
+
+ foreach (const int key, mapRelation->map()->keys())
+ combo->insertItem(key, mapRelation->map()->value(key));
+
+ combo->setCurrentText(index.data().toString());
+
+ return combo;
+}
+
+void MapDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
+{
+ QComboBox *combo = qobject_cast(editor);
+
+ QAbstractItemModel *mdl = model;
+ QModelIndex idx = index;
+
+ if (model->inherits("QAbstractProxyModel")) {
+ QSortFilterProxyModel *proxyModel = qobject_cast(model);
+ if (proxyModel) {
+ mdl = proxyModel->sourceModel();
+ idx = proxyModel->mapToSource(index);
+ }
+ }
+
+ RichSqlModel *sqlModel = qobject_cast(mdl);
+ AbstractRelation *relation = sqlModel->relation(idx.column());
+
+ if (!relation || relation->type() != AbstractRelation::Map)
+ return;
+
+ MapRelation *mapRelation = qobject_cast(relation);
+
+ sqlModel->setData(idx, mapRelation->backwardLookup(combo->currentText()));
+ sqlModel->submit();
+}
diff --git a/delegates/mapdelegate.h b/delegates/mapdelegate.h
new file mode 100644
index 0000000..dddf8a3
--- /dev/null
+++ b/delegates/mapdelegate.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef MAPDELEGATE_H
+#define MAPDELEGATE_H
+
+#include
+
+class MapDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+
+public:
+ explicit MapDelegate(QObject *parent = 0);
+
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+
+ void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
+};
+
+#endif // MAPDELEGATE_H
diff --git a/delegates/numericdelegate.cpp b/delegates/numericdelegate.cpp
new file mode 100644
index 0000000..5eca35b
--- /dev/null
+++ b/delegates/numericdelegate.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "numericdelegate.h"
+
+#include
+#include
+#include
+
+NumericDelegate::NumericDelegate(QValidator *validator, QObject *parent) :
+ QStyledItemDelegate(parent),
+ m_validator(validator)
+{}
+
+QWidget *NumericDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ Q_UNUSED(option)
+ Q_UNUSED(index)
+
+ QLineEdit *editor = new QLineEdit(parent);
+ editor->setValidator(m_validator);
+
+ return editor;
+}
+
+bool NumericDelegate::eventFilter(QObject *object, QEvent *event)
+{
+ if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) {
+ QKeyEvent *keyEvent = static_cast(event);
+
+ if (keyEvent->key() == Qt::Key_Escape) {
+ QApplication::postEvent(object, new QKeyEvent(event->type(), Qt::Key_Enter, Qt::NoModifier));
+ event->ignore();
+ return true;
+ }
+ }
+ return QStyledItemDelegate::eventFilter(object, event);
+}
diff --git a/delegates/numericdelegate.h b/delegates/numericdelegate.h
new file mode 100644
index 0000000..749b5c8
--- /dev/null
+++ b/delegates/numericdelegate.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef NUMERICDELEGATE_H
+#define NUMERICDELEGATE_H
+
+#include
+
+class NumericDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+
+public:
+ explicit NumericDelegate(QValidator *validator, QObject *parent = 0);
+
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+
+protected:
+ bool eventFilter(QObject *object, QEvent *event);
+
+private:
+ const QValidator *m_validator;
+};
+
+#endif // NUMERICDELEGATE_H
diff --git a/delegates/relationaldelegate.cpp b/delegates/relationaldelegate.cpp
new file mode 100644
index 0000000..dc5a4b8
--- /dev/null
+++ b/delegates/relationaldelegate.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "relationaldelegate.h"
+
+#include "resourcemanager.h"
+
+#include
+#include
+#include
+#include
+
+RelationalDelegate::RelationalDelegate(QSqlTableModel *model, int column, bool isEditable, QObject *parent) :
+ QStyledItemDelegate(parent),
+ m_targetModel(model),
+ m_targetColumn(column),
+ m_editable(isEditable),
+ m_map()
+{
+ updateMap(m_targetModel->index(0, 0), m_targetModel->index(m_targetModel->rowCount() - 1, 0));
+
+ connect(m_targetModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(updateMap(QModelIndex,QModelIndex)));
+}
+
+QWidget *RelationalDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ Q_UNUSED(option)
+ Q_UNUSED(index)
+
+ QComboBox *combo = NULL;
+
+ if (m_editable) {
+ combo = new QComboBox(parent);
+ combo->setModel(m_targetModel);
+ combo->setModelColumn(m_targetColumn);
+ }
+
+ return combo;
+}
+
+void RelationalDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
+{
+ QComboBox *combo = qobject_cast(editor);
+
+ QAbstractItemModel *mdl = model;
+ QModelIndex idx = index;
+
+ if (model->inherits("QAbstractProxyModel")) {
+ QSortFilterProxyModel *proxyModel = qobject_cast(model);
+ if (proxyModel) {
+ mdl = proxyModel->sourceModel();
+ idx = proxyModel->mapToSource(index);
+ }
+ }
+
+ QSqlTableModel *sqlModel = qobject_cast(mdl);
+
+ if (combo && sqlModel) {
+ sqlModel->setData(idx, m_map.key(combo->currentText()));
+
+ if (!sqlModel->submit()) {
+ RscMgr::issueMessage(QString(tr("Database Error ")).append(sqlModel->lastError().text()), false);
+ sqlModel->selectRow(idx.row());
+ }
+ }
+}
+
+QString RelationalDelegate::displayText(const QVariant &value, const QLocale &locale) const
+{
+ Q_UNUSED(locale)
+
+ return m_map.value(value.toLongLong());
+}
+
+void RelationalDelegate::updateMap(const QModelIndex &topLeft, const QModelIndex &bottomRight)
+{
+ for (int i = topLeft.row(); i <= bottomRight.row(); ++i) {
+ m_map.insert(m_targetModel->index(i, 0).data().toLongLong(),
+ m_targetModel->index(i, m_targetColumn).data().toString());
+ }
+}
diff --git a/delegates/relationaldelegate.h b/delegates/relationaldelegate.h
new file mode 100644
index 0000000..ef81c0f
--- /dev/null
+++ b/delegates/relationaldelegate.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef RELATIONALDELEGATE_H
+#define RELATIONALDELEGATE_H
+
+#include
+
+class QSqlTableModel;
+
+class RelationalDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+
+public:
+ explicit RelationalDelegate(QSqlTableModel *model, int column, bool isEditable = true, QObject *parent = 0);
+
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+
+ void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
+
+ QString displayText(const QVariant &value, const QLocale &locale) const;
+
+private slots:
+ void updateMap(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+
+private:
+ QSqlTableModel *m_targetModel;
+
+ int m_targetColumn;
+
+ const bool m_editable;
+
+ QMap m_map;
+};
+
+#endif // RELATIONALDELEGATE_H
diff --git a/delegates/sqldelegate.cpp b/delegates/sqldelegate.cpp
new file mode 100644
index 0000000..ca1682f
--- /dev/null
+++ b/delegates/sqldelegate.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "sqldelegate.h"
+
+#include "sqlrelation.h"
+#include "richsqlmodel.h"
+
+#include
+#include
+
+SqlDelegate::SqlDelegate(bool isEditable, QObject *parent) :
+ QStyledItemDelegate(parent),
+ m_isEditable(isEditable)
+{}
+
+QWidget *SqlDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ Q_UNUSED(option)
+
+ const QAbstractItemModel *model = index.model();
+
+ const QAbstractItemModel *mdl = model;
+ QModelIndex idx = index;
+ AbstractRelation *relation = NULL;
+
+ if (model->inherits("QAbstractProxyModel")) {
+ const QSortFilterProxyModel *proxyModel = qobject_cast(model);
+ if (proxyModel) {
+ mdl = proxyModel->sourceModel();
+ idx = proxyModel->mapToSource(index);
+ relation = qobject_cast(mdl)->relation(idx.column());
+ }
+ } else {
+ relation = qobject_cast(model)->relation(index.column());
+ }
+
+ if (!relation || relation->type() != AbstractRelation::Sql)
+ return NULL;
+
+ SqlRelation *sqlRelation = qobject_cast(relation);
+ QSqlTableModel *sqlRemoteModel = const_cast(sqlRelation->remoteModel());
+
+ if (m_isEditable) {
+ QComboBox *combo = new QComboBox(parent);
+ combo->setModel(sqlRemoteModel);
+ combo->setModelColumn(sqlRelation->displayColumn());
+ combo->setCurrentText(sqlRelation->forwardLookup(idx.data(Qt::EditRole).toLongLong()));
+ return combo;
+ }
+
+ return NULL;
+}
+
+void SqlDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
+{
+ QComboBox *combo = qobject_cast(editor);
+
+ QAbstractItemModel *mdl = model;
+ QModelIndex idx = index;
+
+ if (model->inherits("QAbstractProxyModel")) {
+ QSortFilterProxyModel *proxyModel = qobject_cast(model);
+ if (proxyModel) {
+ mdl = proxyModel->sourceModel();
+ idx = proxyModel->mapToSource(index);
+ }
+ }
+
+ RichSqlModel *sqlModel = qobject_cast(mdl);
+
+ AbstractRelation *relation = sqlModel->relation(idx.column());
+
+ if (!relation || relation->type() != AbstractRelation::Sql)
+ return;
+
+ SqlRelation *sqlRelation = qobject_cast(relation);
+
+ sqlModel->setData(idx, sqlRelation->backwardLookup(combo->currentText()));
+ sqlModel->submit();
+}
diff --git a/delegates/sqldelegate.h b/delegates/sqldelegate.h
new file mode 100644
index 0000000..74ccbfa
--- /dev/null
+++ b/delegates/sqldelegate.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef SQLDELEGATE_H
+#define SQLDELEGATE_H
+
+#include
+
+class SqlDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+
+public:
+ explicit SqlDelegate(bool isEditable, QObject *parent = 0);
+
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+
+ void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
+
+private:
+ const bool m_isEditable;
+};
+
+#endif // SQLDELEGATE_H
diff --git a/delegates/uniquedelegate.cpp b/delegates/uniquedelegate.cpp
new file mode 100644
index 0000000..27afd5f
--- /dev/null
+++ b/delegates/uniquedelegate.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "uniquedelegate.h"
+
+#include "resourcemanager.h"
+
+#include
+#include
+#include
+#include
+
+UniqueDelegate::UniqueDelegate(QObject *parent) :
+ QStyledItemDelegate(parent)
+{}
+
+void UniqueDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
+{
+ QLineEdit *lineEdit = qobject_cast(editor);
+
+ QAbstractItemModel *mdl = model;
+ QModelIndex idx = index;
+
+ if (model->inherits("QAbstractProxyModel")) {
+ QSortFilterProxyModel *proxyModel = qobject_cast(model);
+ if (proxyModel) {
+ mdl = proxyModel->sourceModel();
+ idx = proxyModel->mapToSource(index);
+ }
+ }
+
+ QSqlTableModel *sqlModel = qobject_cast(mdl);
+
+ if (lineEdit && sqlModel) {
+ sqlModel->setData(idx, lineEdit->text().trimmed());
+
+ if (!sqlModel->submit()) {
+ RscMgr::issueMessage(QString(tr("Database Error ")).append(sqlModel->lastError().text()), false);
+ sqlModel->selectRow(idx.row());
+ }
+ }
+}
diff --git a/delegates/uniquedelegate.h b/delegates/uniquedelegate.h
new file mode 100644
index 0000000..3169c69
--- /dev/null
+++ b/delegates/uniquedelegate.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef UNIQUEDELEGATE_H
+#define UNIQUEDELEGATE_H
+
+#include
+
+class UniqueDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+
+public:
+ explicit UniqueDelegate(QObject *parent = 0);
+
+ void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
+};
+
+#endif // UNIQUEDELEGATE_H
diff --git a/furqan.ico b/furqan.ico
new file mode 100644
index 0000000..75854c0
Binary files /dev/null and b/furqan.ico differ
diff --git a/handlers/databasehandler.cpp b/handlers/databasehandler.cpp
new file mode 100644
index 0000000..d987a86
--- /dev/null
+++ b/handlers/databasehandler.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "databasehandler.h"
+#include "resourcemanager.h"
+
+#include
+#include
+
+DatabaseHandler::DatabaseHandler(QObject *parent) :
+ QObject(parent),
+ databaseFileExtension(".fdb")
+{
+ m_database = QSqlDatabase::addDatabase("QIBASE");
+ m_database.setDatabaseName(RscMgr::settingHandler()->databasePath());
+ m_database.setUserName("SYSDBA");
+ m_database.open();
+}
+
+DatabaseHandler::~DatabaseHandler() {
+ if (m_database.isOpen())
+ m_database.close();
+}
+
+DatabaseHandler *DatabaseHandler::singleton()
+{
+ static DatabaseHandler *databaseHandler = NULL;
+
+ if (!databaseHandler)
+ databaseHandler = new DatabaseHandler(qApp);
+
+ return databaseHandler;
+}
+
+QSqlDatabase &DatabaseHandler::connection()
+{
+ return m_database;
+}
+
+bool DatabaseHandler::createNewDatabase(const QString &newDatabasePath)
+{
+ return copyDatabase(":/empty-database", newDatabasePath);
+}
+
+bool DatabaseHandler::ChangeCurrentDatabase(const QString &newDatabasePath)
+{
+ // Check whether the given path ends with the extension indicated to by "databaseFileExtension" data member.
+ if (!isPathValid(newDatabasePath))
+ return false;
+
+ if (m_database.isOpen())
+ m_database.close();
+
+ m_database.setDatabaseName(newDatabasePath);
+
+ if (!m_database.open()) {
+ return false;
+ }
+
+ RscMgr::settingHandler()->setDatabasePath(newDatabasePath);
+
+ emit currentDatabaseChanged(newDatabasePath);
+
+ return true;
+}
+
+bool DatabaseHandler::backupCurrentDatabase(const QString &backupDatabasePath)
+{
+ return copyDatabase(RscMgr::settingHandler()->databasePath(), backupDatabasePath);
+}
+
+bool DatabaseHandler::isPathValid(const QString &path) const
+{
+ return path.endsWith(databaseFileExtension);
+}
+
+void DatabaseHandler::validatePath(QString &path) const
+{
+ if (!path.endsWith(databaseFileExtension))
+ path.append(databaseFileExtension);
+}
+
+bool DatabaseHandler::copyDatabase(const QString &sourcePath, const QString &targetPath)
+{
+ QFile file;
+ file.setFileName(sourcePath);
+
+ if (file.copy(targetPath)) {
+ QFile(targetPath).setPermissions(QFile::ReadOther | QFile::WriteOther);
+ return true;
+ }
+
+ return false;
+}
diff --git a/handlers/databasehandler.h b/handlers/databasehandler.h
new file mode 100644
index 0000000..c6400e3
--- /dev/null
+++ b/handlers/databasehandler.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef DATABASEHANDLER_H
+#define DATABASEHANDLER_H
+
+#include
+#include
+
+class DatabaseHandler : public QObject
+{
+ Q_OBJECT
+
+public:
+ static DatabaseHandler *singleton();
+
+ QSqlDatabase &connection();
+
+ bool createNewDatabase(const QString &newDatabasePath);
+
+ bool ChangeCurrentDatabase(const QString &newDatabasePath);
+
+ bool backupCurrentDatabase(const QString &backupDatabasePath);
+
+ ~DatabaseHandler();
+
+signals:
+ void currentDatabaseChanged(const QString &) const;
+
+private:
+ explicit DatabaseHandler(QObject *parent = 0);
+
+ const QString databaseFileExtension;
+
+ bool isPathValid(const QString &path) const;
+
+ void validatePath(QString &path) const;
+
+ bool copyDatabase(const QString &sourcePath, const QString &targetPath);
+
+ QSqlDatabase m_database;
+};
+
+#endif // DATABASEHANDLER_H
diff --git a/handlers/maphandler.cpp b/handlers/maphandler.cpp
new file mode 100644
index 0000000..c4dd92e
--- /dev/null
+++ b/handlers/maphandler.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "maphandler.h"
+
+#include "resourcemanager.h"
+
+#include
+
+MapHandler::MapHandler(QObject *parent) :
+ QObject(parent)
+{
+ initialize();
+
+ mapMaps();
+
+ connect(RscMgr::translatorHandler(), SIGNAL(languageChanged()), SLOT(initialize()));
+}
+
+void MapHandler::initialize()
+{
+ m_genderMap.clear();
+ m_genderMap.insert(NS_GENDER::NONE, tr("None"));
+ m_genderMap.insert(NS_GENDER::MALE, tr("Male"));
+ m_genderMap.insert(NS_GENDER::FEMALE, tr("Female"));
+
+ m_levelMap.clear();
+ m_levelMap.insert(NS_LEVEL::NONE, tr("None"));
+ m_levelMap.insert(NS_LEVEL::BASIC, tr("Basic"));
+ m_levelMap.insert(NS_LEVEL::INTERMEDIATE, tr("Intermediate"));
+ m_levelMap.insert(NS_LEVEL::ADVANCED, tr("Advanced"));
+
+ m_semesterMap.clear();
+ m_semesterMap.insert(NS_SEMESTER::NONE, tr("None"));
+ m_semesterMap.insert(NS_SEMESTER::FIRST, tr("First"));
+ m_semesterMap.insert(NS_SEMESTER::SECOND, tr("Second"));
+
+ m_competitionMap.clear();
+ m_competitionMap.insert(NS_COMPETITION_TYPE::NONE, tr("None"));
+ m_competitionMap.insert(NS_COMPETITION_TYPE::DAILY, tr("Daily"));
+ m_competitionMap.insert(NS_COMPETITION_TYPE::WEEKLY, tr("Weekly"));
+ m_competitionMap.insert(NS_COMPETITION_TYPE::QUARTERLY, tr("Quarterly"));
+
+ m_recitalMap.clear();
+ m_recitalMap.insert(NS_RECITAL::NONE, tr("None"));
+ m_recitalMap.insert(NS_RECITAL::READING, tr("Reading"));
+ m_recitalMap.insert(NS_RECITAL::MEMORIZING, tr("Memorizing"));
+ m_recitalMap.insert(NS_RECITAL::REVIEWING, tr("Reviewing"));
+}
+
+void MapHandler::mapMaps()
+{
+ m_mapMap.clear();
+ m_mapMap.insert(NS_MAP::GENDER, &m_genderMap);
+ m_mapMap.insert(NS_MAP::LEVEL, &m_levelMap);
+ m_mapMap.insert(NS_MAP::SEMESTER, &m_semesterMap);
+ m_mapMap.insert(NS_MAP::COMPETITION, &m_competitionMap);
+ m_mapMap.insert(NS_MAP::RECITAL, &m_recitalMap);
+}
+
+MapHandler *MapHandler::singleton()
+{
+ static MapHandler *mapHandler = NULL;
+
+ if (!mapHandler)
+ mapHandler = new MapHandler(qApp);
+
+ return mapHandler;
+}
+
+const QMap *MapHandler::map(NS_MAP::MAP map) const
+{
+ return m_mapMap.value(map);
+}
diff --git a/handlers/maphandler.h b/handlers/maphandler.h
new file mode 100644
index 0000000..18a4862
--- /dev/null
+++ b/handlers/maphandler.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef MAPHANDLER_H
+#define MAPHANDLER_H
+
+#include
+#include
+
+#include "maprelation.h"
+#include "mapenumeration.h"
+
+class MapHandler : public QObject
+{
+ Q_OBJECT
+
+public:
+ static MapHandler *singleton();
+
+ const QMap *map(NS_MAP::MAP) const;
+
+private slots:
+ void mapMaps();
+
+ void initialize();
+
+private:
+ explicit MapHandler(QObject *parent = 0);
+
+ QMap m_genderMap;
+ QMap m_levelMap;
+ QMap m_semesterMap;
+ QMap m_competitionMap;
+ QMap m_recitalMap;
+
+ QMap *> m_mapMap;
+};
+
+#endif // MAPHANDLER_H
diff --git a/handlers/modelhandler.cpp b/handlers/modelhandler.cpp
new file mode 100644
index 0000000..663debb
--- /dev/null
+++ b/handlers/modelhandler.cpp
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "modelhandler.h"
+
+#include "resourcemanager.h"
+#include "richsqlmodel.h"
+#include "maprelation.h"
+#include "sqlrelation.h"
+
+#include
+#include
+
+ModelHandler::ModelHandler(QObject *parent) :
+ QObject(parent),
+ m_classModel(new RichSqlModel(this)),
+ m_courseModel(new RichSqlModel(this)),
+ m_studentModel(new RichSqlModel(this)),
+ m_teacherModel(new RichSqlModel(this)),
+ m_teachingModel(new RichSqlModel(this)),
+ m_resultModel(new RichSqlModel(this)),
+ m_quranModel(new RichSqlModel(this)),
+ m_competitionModel(new RichSqlModel(this)),
+ m_competitorModel(new RichSqlModel(this)),
+ m_jobModel(new RichSqlModel(this)),
+ m_employeeModel(new RichSqlModel(this)),
+ m_previewModel(new QStandardItemModel(3, 3, this)),
+ m_modelMap()
+{
+ mapModels();
+
+ initializeModels();
+ initializeHeaders();
+ initializePreviewModel();
+
+ connect(RscMgr::translatorHandler(), SIGNAL(languageChanged()), SLOT(initializeHeaders()));
+ connect(RscMgr::translatorHandler(), SIGNAL(languageChanged()), SLOT(initializePreviewModel()));
+ connect(RscMgr::databaseHandler(), SIGNAL(currentDatabaseChanged(QString)), SLOT(reset()));
+}
+
+ModelHandler *ModelHandler::singleton()
+{
+ static ModelHandler *modelHandler = NULL;
+
+ if (!modelHandler)
+ modelHandler = new ModelHandler(qApp);
+
+ return modelHandler;
+}
+
+void ModelHandler::initializeModels()
+{
+ m_classModel->setTable("CLASS");
+ m_classModel->setSort(NS_CLASS::ID, Qt::AscendingOrder);
+ m_classModel->setEditStrategy(QSqlTableModel::OnFieldChange);
+ m_classModel->setRelation(NS_CLASS::LEVEL, new MapRelation(RscMgr::mapHandler()->map(NS_MAP::LEVEL), m_classModel));
+ m_classModel->select();
+
+ m_courseModel->setTable("COURSE");
+ m_courseModel->setSort(NS_COURSE::ID, Qt::AscendingOrder);
+ m_courseModel->setEditStrategy(QSqlTableModel::OnFieldChange);
+ m_courseModel->setRelation(NS_COURSE::SEMESTER, new MapRelation(RscMgr::mapHandler()->map(NS_MAP::SEMESTER), m_courseModel));
+ m_courseModel->select();
+
+ m_studentModel->setTable("STUDENT");
+ m_studentModel->setSort(NS_STUDENT::ID, Qt::AscendingOrder);
+ m_studentModel->setEditStrategy(QSqlTableModel::OnFieldChange);
+ m_studentModel->setRelation(NS_STUDENT::GENDER, new MapRelation(RscMgr::mapHandler()->map(NS_MAP::GENDER), m_studentModel));
+ m_studentModel->setRelation(NS_STUDENT::LEVEL, new MapRelation(RscMgr::mapHandler()->map(NS_MAP::LEVEL), m_studentModel));
+ m_studentModel->setRelation(NS_STUDENT::CLASS, new SqlRelation(m_classModel, NS_CLASS::ID, NS_CLASS::NAME, m_studentModel));
+ m_studentModel->select();
+
+ m_teacherModel->setTable("TEACHER");
+ m_teacherModel->setSort(NS_TEACHER::ID, Qt::AscendingOrder);
+ m_teacherModel->setEditStrategy(QSqlTableModel::OnFieldChange);
+ m_teacherModel->setRelation(NS_TEACHER::GENDER, new MapRelation(RscMgr::mapHandler()->map(NS_MAP::GENDER), m_teacherModel));
+ m_teacherModel->select();
+
+ m_teachingModel->setTable("TEACHING");
+ m_teachingModel->setSort(NS_TEACHING::ID, Qt::AscendingOrder);
+ m_teachingModel->setEditStrategy(QSqlTableModel::OnFieldChange);
+ m_teachingModel->setRelation(NS_TEACHING::TEACHER, new SqlRelation(m_teacherModel, NS_TEACHER::ID, NS_TEACHER::FULL_NAME, m_teachingModel));
+ m_teachingModel->setRelation(NS_TEACHING::CLASS, new SqlRelation(m_classModel, NS_CLASS::ID, NS_CLASS::NAME, m_teachingModel));
+ m_teachingModel->setRelation(NS_TEACHING::COURSE, new SqlRelation(m_courseModel, NS_COURSE::ID, NS_COURSE::NAME, m_teachingModel));
+ m_teachingModel->select();
+
+ m_resultModel->setTable("RESULT");
+ m_resultModel->setSort(NS_RESULT::ID, Qt::AscendingOrder);
+ m_resultModel->setEditStrategy(QSqlTableModel::OnFieldChange);
+ m_resultModel->setRelation(NS_RESULT::COURSE, new SqlRelation(m_courseModel, NS_COURSE::ID, NS_COURSE::NAME, m_resultModel));
+ m_resultModel->setRelation(NS_RESULT::STUDENT, new SqlRelation(m_studentModel, NS_STUDENT::ID, NS_STUDENT::FULL_NAME, m_resultModel));
+ m_resultModel->select();
+
+ m_quranModel->setTable("QURAN");
+ m_quranModel->setSort(NS_QURAN::ID, Qt::AscendingOrder);
+ m_quranModel->setEditStrategy(QSqlTableModel::OnFieldChange);
+ m_quranModel->setRelation(NS_QURAN::RECITAL_TYPE, new MapRelation(RscMgr::mapHandler()->map(NS_MAP::RECITAL), m_quranModel));
+ m_quranModel->setRelation(NS_QURAN::STUDENT, new SqlRelation(m_studentModel, NS_STUDENT::ID, NS_STUDENT::FULL_NAME, m_quranModel));
+ m_quranModel->select();
+
+ m_competitionModel->setTable("COMPETITION");
+ m_competitionModel->setSort(NS_COMPETITION::ID, Qt::AscendingOrder);
+ m_competitionModel->setEditStrategy(QSqlTableModel::OnFieldChange);
+ m_competitionModel->setRelation(NS_COMPETITION::TYPE, new MapRelation(RscMgr::mapHandler()->map(NS_MAP::COMPETITION), m_competitionModel));
+ m_competitionModel->select();
+
+ m_competitorModel->setTable("COMPETITOR");
+ m_competitorModel->setSort(NS_COMPETITOR::ID, Qt::AscendingOrder);
+ m_competitorModel->setEditStrategy(QSqlTableModel::OnFieldChange);
+ m_competitorModel->setRelation(NS_COMPETITOR::COMPETITION, new SqlRelation(m_competitionModel, NS_COMPETITION::ID, NS_COMPETITION::NAME, m_competitorModel));
+ m_competitorModel->setRelation(NS_COMPETITOR::STUDENT, new SqlRelation(m_studentModel, NS_STUDENT::ID, NS_STUDENT::FULL_NAME, m_competitorModel));
+ m_competitorModel->select();
+
+ m_jobModel->setTable("JOB");
+ m_jobModel->setSort(NS_JOB::ID, Qt::AscendingOrder);
+ m_jobModel->setEditStrategy(QSqlTableModel::OnFieldChange);
+ m_jobModel->select();
+
+ m_employeeModel->setTable("EMPLOYEE");
+ m_employeeModel->setSort(NS_EMPLOYEE::ID, Qt::AscendingOrder);
+ m_employeeModel->setEditStrategy(QSqlTableModel::OnFieldChange);
+ m_employeeModel->setRelation(NS_EMPLOYEE::GENDER, new MapRelation(RscMgr::mapHandler()->map(NS_MAP::GENDER), m_employeeModel));
+ m_employeeModel->setRelation(NS_EMPLOYEE::JOB, new SqlRelation(m_jobModel, NS_JOB::ID, NS_JOB::NAME, m_employeeModel));
+ m_employeeModel->select();
+}
+
+void ModelHandler::initializeHeaders()
+{
+ m_classModel->setHeaderData(NS_CLASS::ID, Qt::Horizontal, tr("ID"));
+ m_classModel->setHeaderData(NS_CLASS::NAME, Qt::Horizontal, tr("Name"));
+ m_classModel->setHeaderData(NS_CLASS::LEVEL, Qt::Horizontal, tr("Level"));
+
+ m_courseModel->setHeaderData(NS_COURSE::ID, Qt::Horizontal, tr("ID"));
+ m_courseModel->setHeaderData(NS_COURSE::NAME, Qt::Horizontal, tr("Name"));
+ m_courseModel->setHeaderData(NS_COURSE::SEMESTER, Qt::Horizontal, tr("Semester"));
+
+ m_studentModel->setHeaderData(NS_STUDENT::ID, Qt::Horizontal, tr("ID"));
+ m_studentModel->setHeaderData(NS_STUDENT::FULL_NAME, Qt::Horizontal, tr("Full Name"));
+ m_studentModel->setHeaderData(NS_STUDENT::FATHER_NAME, Qt::Horizontal, tr("Father Name"));
+ m_studentModel->setHeaderData(NS_STUDENT::GENDER, Qt::Horizontal, tr("Gender"));
+ m_studentModel->setHeaderData(NS_STUDENT::BIRTH_PLACE, Qt::Horizontal, tr("Birth Place"));
+ m_studentModel->setHeaderData(NS_STUDENT::BIRTH_DATE, Qt::Horizontal, tr("Birth Date"));
+ m_studentModel->setHeaderData(NS_STUDENT::RESIDENCY, Qt::Horizontal, tr("Residency"));
+ m_studentModel->setHeaderData(NS_STUDENT::NATIONALITY, Qt::Horizontal, tr("Nationality"));
+ m_studentModel->setHeaderData(NS_STUDENT::NATIONAL_ID, Qt::Horizontal, tr("National Number"));
+ m_studentModel->setHeaderData(NS_STUDENT::MOBILE, Qt::Horizontal, tr("Mobile"));
+ m_studentModel->setHeaderData(NS_STUDENT::FATHER_JOB, Qt::Horizontal, tr("Father Job"));
+ m_studentModel->setHeaderData(NS_STUDENT::LEVEL, Qt::Horizontal, tr("Level"));
+ m_studentModel->setHeaderData(NS_STUDENT::CLASS, Qt::Horizontal, tr("Class"));
+
+ m_teacherModel->setHeaderData(NS_TEACHER::ID, Qt::Horizontal, tr("ID"));
+ m_teacherModel->setHeaderData(NS_TEACHER::FULL_NAME, Qt::Horizontal, tr("Full Name"));
+ m_teacherModel->setHeaderData(NS_TEACHER::FATHER_NAME, Qt::Horizontal, tr("Father Name"));
+ m_teacherModel->setHeaderData(NS_TEACHER::GENDER, Qt::Horizontal, tr("Gender"));
+ m_teacherModel->setHeaderData(NS_TEACHER::BIRTH_PLACE, Qt::Horizontal, tr("Birth Place"));
+ m_teacherModel->setHeaderData(NS_TEACHER::BIRTH_DATE, Qt::Horizontal, tr("Birth Date"));
+ m_teacherModel->setHeaderData(NS_TEACHER::RESIDENCY, Qt::Horizontal, tr("Residency"));
+ m_teacherModel->setHeaderData(NS_TEACHER::NATIONALITY, Qt::Horizontal, tr("Nationality"));
+ m_teacherModel->setHeaderData(NS_TEACHER::NATIONAL_ID, Qt::Horizontal, tr("National Number"));
+ m_teacherModel->setHeaderData(NS_TEACHER::MOBILE, Qt::Horizontal, tr("Mobile"));
+ m_teacherModel->setHeaderData(NS_TEACHER::QUALIFICATION, Qt::Horizontal, tr("Qualification"));
+ m_teacherModel->setHeaderData(NS_TEACHER::EXPERIENCE, Qt::Horizontal, tr("Experience"));
+
+ m_teachingModel->setHeaderData(NS_TEACHING::ID, Qt::Horizontal, tr("ID"));
+ m_teachingModel->setHeaderData(NS_TEACHING::TEACHER, Qt::Horizontal, tr("Teacher"));
+ m_teachingModel->setHeaderData(NS_TEACHING::CLASS, Qt::Horizontal, tr("Class"));
+ m_teachingModel->setHeaderData(NS_TEACHING::COURSE, Qt::Horizontal, tr("Course"));
+
+ m_resultModel->setHeaderData(NS_RESULT::ID, Qt::Horizontal, tr("ID"));
+ m_resultModel->setHeaderData(NS_RESULT::COURSE, Qt::Horizontal, tr("Course"));
+ m_resultModel->setHeaderData(NS_RESULT::STUDENT, Qt::Horizontal, tr("Student"));
+ m_resultModel->setHeaderData(NS_RESULT::RESULT, Qt::Horizontal, tr("Result"));
+
+ m_quranModel->setHeaderData(NS_QURAN::ID, Qt::Horizontal, tr("ID"));
+ m_quranModel->setHeaderData(NS_QURAN::STUDENT, Qt::Horizontal, tr("Student"));
+ m_quranModel->setHeaderData(NS_QURAN::RECITAL_TYPE, Qt::Horizontal, tr("Recital Type"));
+ m_quranModel->setHeaderData(NS_QURAN::FROM_PAGE, Qt::Horizontal, tr("From Page"));
+ m_quranModel->setHeaderData(NS_QURAN::TO_PAGE, Qt::Horizontal, tr("To Page"));
+ m_quranModel->setHeaderData(NS_QURAN::DATE, Qt::Horizontal, tr("Date"));
+
+ m_competitionModel->setHeaderData(NS_COMPETITION::ID, Qt::Horizontal, tr("ID"));
+ m_competitionModel->setHeaderData(NS_COMPETITION::NAME, Qt::Horizontal, tr("Name"));
+ m_competitionModel->setHeaderData(NS_COMPETITION::TYPE, Qt::Horizontal, tr("Type"));
+ m_competitionModel->setHeaderData(NS_COMPETITION::PARTS, Qt::Horizontal, tr("Part(s)"));
+ m_competitionModel->setHeaderData(NS_COMPETITION::DATE, Qt::Horizontal, tr("Date"));
+
+ m_competitorModel->setHeaderData(NS_COMPETITOR::ID, Qt::Horizontal, tr("ID"));
+ m_competitorModel->setHeaderData(NS_COMPETITOR::COMPETITION, Qt::Horizontal, tr("Competition"));
+ m_competitorModel->setHeaderData(NS_COMPETITOR::STUDENT, Qt::Horizontal, tr("Student"));
+ m_competitorModel->setHeaderData(NS_COMPETITOR::RANK, Qt::Horizontal, tr("Rank"));
+
+ m_jobModel->setHeaderData(NS_JOB::ID, Qt::Horizontal, tr("ID"));
+ m_jobModel->setHeaderData(NS_JOB::NAME, Qt::Horizontal, tr("Name"));
+
+ m_employeeModel->setHeaderData(NS_EMPLOYEE::ID, Qt::Horizontal, tr("ID"));
+ m_employeeModel->setHeaderData(NS_EMPLOYEE::FULL_NAME, Qt::Horizontal, tr("Full Name"));
+ m_employeeModel->setHeaderData(NS_EMPLOYEE::FATHER_NAME, Qt::Horizontal, tr("Father Name"));
+ m_employeeModel->setHeaderData(NS_EMPLOYEE::GENDER, Qt::Horizontal, tr("Gender"));
+ m_employeeModel->setHeaderData(NS_EMPLOYEE::BIRTH_PLACE, Qt::Horizontal, tr("Birth Place"));
+ m_employeeModel->setHeaderData(NS_EMPLOYEE::BIRTH_DATE, Qt::Horizontal, tr("Birth Date"));
+ m_employeeModel->setHeaderData(NS_EMPLOYEE::RESIDENCY, Qt::Horizontal, tr("Residency"));
+ m_employeeModel->setHeaderData(NS_EMPLOYEE::NATIONALITY, Qt::Horizontal, tr("Nationality"));
+ m_employeeModel->setHeaderData(NS_EMPLOYEE::NATIONAL_ID, Qt::Horizontal, tr("National Number"));
+ m_employeeModel->setHeaderData(NS_EMPLOYEE::MOBILE, Qt::Horizontal, tr("Mobile"));
+ m_employeeModel->setHeaderData(NS_EMPLOYEE::JOB, Qt::Horizontal, tr("Job"));
+ m_employeeModel->setHeaderData(NS_EMPLOYEE::OTHER_JOB, Qt::Horizontal, tr("Other Job"));
+}
+
+void ModelHandler::initializePreviewModel()
+{
+ for (int column = 0; column < m_previewModel->columnCount(); ++column) {
+ m_previewModel->setHeaderData(column, Qt::Horizontal, tr("Header") + QString("%1").arg(column + 1));
+ }
+
+ for (int row = 0; row < m_previewModel->rowCount(); ++row) {
+ for (int column = 0; column < m_previewModel->columnCount(); ++column) {
+ QStandardItem *item = new QStandardItem(tr("Cell") + QString("%1%2").arg(column + 1).arg(row + 1));
+ m_previewModel->setItem(row, column, item);
+ }
+ }
+}
+
+void ModelHandler::mapModels()
+{
+ m_modelMap.clear();
+ m_modelMap.insert(NS_TABLE::CLASS, m_classModel);
+ m_modelMap.insert(NS_TABLE::COURSE, m_courseModel);
+ m_modelMap.insert(NS_TABLE::STUDENT, m_studentModel);
+ m_modelMap.insert(NS_TABLE::TEACHER, m_teacherModel);
+ m_modelMap.insert(NS_TABLE::TEACHING, m_teachingModel);
+ m_modelMap.insert(NS_TABLE::RESULT, m_resultModel);
+ m_modelMap.insert(NS_TABLE::QURAN, m_quranModel);
+ m_modelMap.insert(NS_TABLE::COMPETITION, m_competitionModel);
+ m_modelMap.insert(NS_TABLE::COMPETITOR, m_competitorModel);
+ m_modelMap.insert(NS_TABLE::JOB, m_jobModel);
+ m_modelMap.insert(NS_TABLE::EMPLOYEE, m_employeeModel);
+}
+
+void ModelHandler::reset()
+{
+ foreach (RichSqlModel *model, m_modelMap.values()) {
+ //To use the new database connection, we reset the table name.
+ model->setTable(model->tableName());
+ model->select();
+ }
+
+ initializeHeaders();
+}
+
+QSqlTableModel *ModelHandler::model(NS_TABLE::TABLE table) const
+{
+ return m_modelMap.value(table, NULL);
+}
+
+QStandardItemModel *ModelHandler::previewModel() const
+{
+ return m_previewModel;
+}
+
+void ModelHandler::insertRow(NS_TABLE::TABLE table, const QMap &map) const
+{
+ QSqlTableModel *m = model(table);
+
+ m->insertRow(0);
+ m->setData(m->index(0, 0), newRowId(m));
+
+ foreach (const QVariant &value, map)
+ m->setData(m->index(0, map.key(value)), value);
+
+ m->submit();
+}
+
+long long ModelHandler::newRowId(const QSqlTableModel *model) const
+{
+ QSqlQuery qry(QString("SELECT MAX(ID) FROM %1 ;").arg(model->tableName()), model->database());
+ qry.exec();
+ qry.next();
+
+ return qry.value(0).toLongLong() + 1;
+}
+
+void ModelHandler::removeRow(NS_TABLE::TABLE table, int row) const
+{
+ QSqlTableModel *m = model(table);
+
+ m->removeRow(row);
+ m->submit();
+ m->select();
+}
diff --git a/handlers/modelhandler.h b/handlers/modelhandler.h
new file mode 100644
index 0000000..62d040b
--- /dev/null
+++ b/handlers/modelhandler.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef MODELHANDLER_H
+#define MODELHANDLER_H
+
+#include
+#include
+#include
+#include
+#include
+
+#include "sqlenumeration.h"
+
+class RichSqlModel;
+
+class ModelHandler : public QObject
+{
+ Q_OBJECT
+
+public:
+ static ModelHandler *singleton();
+
+ QSqlTableModel *model(NS_TABLE::TABLE) const;
+
+ QStandardItemModel *previewModel() const;
+
+ void insertRow(NS_TABLE::TABLE table, const QMap &map = QMap()) const;
+
+ void removeRow(NS_TABLE::TABLE table, int row) const;
+
+ long long newRowId(const QSqlTableModel *model) const;
+
+private slots:
+ void initializeModels();
+ void initializeHeaders();
+ void initializePreviewModel();
+
+ void mapModels();
+ void reset();
+
+private:
+ explicit ModelHandler(QObject *parent = 0);
+
+ RichSqlModel *m_classModel;
+ RichSqlModel *m_courseModel;
+ RichSqlModel *m_studentModel;
+ RichSqlModel *m_teacherModel;
+ RichSqlModel *m_teachingModel;
+ RichSqlModel *m_resultModel;
+ RichSqlModel *m_quranModel;
+ RichSqlModel *m_competitionModel;
+ RichSqlModel *m_competitorModel;
+ RichSqlModel *m_jobModel;
+ RichSqlModel *m_employeeModel;
+
+ QStandardItemModel *m_previewModel;
+
+ QMap m_modelMap;
+};
+
+#endif // MODELHANDLER_H
diff --git a/handlers/printerhandler.cpp b/handlers/printerhandler.cpp
new file mode 100644
index 0000000..dc9b6a1
--- /dev/null
+++ b/handlers/printerhandler.cpp
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "printerhandler.h"
+
+#include "printoption.h"
+#include "resourcemanager.h"
+
+#include
+#include
+#include
+#include
+#include
+
+PrinterHandler::PrinterHandler(QObject *parent) :
+ QObject(parent)
+{
+ initialize();
+
+ connect(RscMgr::settingHandler(), SIGNAL(settingChanged()), SLOT(initialize()));
+}
+
+PrinterHandler *PrinterHandler::singleton()
+{
+ static PrinterHandler *printerHandler = NULL;
+
+ if (!printerHandler)
+ printerHandler = new PrinterHandler(qApp);
+
+ return printerHandler;
+}
+
+QPrinter *PrinterHandler::nativePrinter()
+{
+ return &m_nativePrinter;
+}
+
+QPrinter *PrinterHandler::previewPrinter()
+{
+ return &m_previewPrinter;
+}
+
+QPrinter *PrinterHandler::settingPreviewPrinter()
+{
+ return &m_settingPreviewPrinter;
+}
+
+void PrinterHandler::initialize()
+{
+ m_nativePrinter.setOutputFormat(QPrinter::NativeFormat);
+ m_nativePrinter.setPaperSize(RscMgr::settingHandler()->printerPageSize());
+ m_nativePrinter.setOrientation(RscMgr::settingHandler()->printerOrientation());
+ m_nativePrinter.setColorMode(RscMgr::settingHandler()->printerColorMode());
+ m_nativePrinter.setPageMargins(RscMgr::settingHandler()->printerLeftMargin(),
+ RscMgr::settingHandler()->printerTopMargin(),
+ RscMgr::settingHandler()->printerRightMargin(),
+ RscMgr::settingHandler()->printerBottomMargin(),
+ QPrinter::Millimeter);
+
+ m_previewPrinter.setOutputFormat(QPrinter::PdfFormat);
+ m_previewPrinter.setPaperSize(RscMgr::settingHandler()->printerPageSize());
+ m_previewPrinter.setOrientation(RscMgr::settingHandler()->printerOrientation());
+ m_previewPrinter.setColorMode(RscMgr::settingHandler()->printerColorMode());
+ m_previewPrinter.setPageMargins(RscMgr::settingHandler()->printerLeftMargin(),
+ RscMgr::settingHandler()->printerTopMargin(),
+ RscMgr::settingHandler()->printerRightMargin(),
+ RscMgr::settingHandler()->printerBottomMargin(),
+ QPrinter::Millimeter);
+
+ m_settingPreviewPrinter.setOutputFormat(QPrinter::PdfFormat);
+ m_settingPreviewPrinter.setPaperSize(RscMgr::settingHandler()->printerPageSize());
+ m_settingPreviewPrinter.setOrientation(RscMgr::settingHandler()->printerOrientation());
+ m_settingPreviewPrinter.setColorMode(RscMgr::settingHandler()->printerColorMode());
+ m_settingPreviewPrinter.setPageMargins(RscMgr::settingHandler()->printerLeftMargin(),
+ RscMgr::settingHandler()->printerTopMargin(),
+ RscMgr::settingHandler()->printerRightMargin(),
+ RscMgr::settingHandler()->printerBottomMargin(),
+ QPrinter::Millimeter);
+}
+
+void PrinterHandler::print(QAbstractItemModel *model,
+ PrintOption *printOption,
+ QPrinter *printer)
+{
+ QTextDocument doc;
+ doc.setDocumentMargin(1);
+ doc.setTextWidth(printer->pageRect().width());
+ doc.setPageSize(printer->pageRect().size());
+ doc.setDefaultTextOption(QTextOption(RscMgr::dir() == Qt::RightToLeft ? Qt::AlignRight : Qt::AlignLeft));
+
+ QTextCursor curser(&doc);
+
+ if (RscMgr::settingHandler()->headerType() == NS_HeaderType::Image) {
+
+ QTextImageFormat textImageFormat;
+ textImageFormat.setName(RscMgr::settingHandler()->headerImagePath());
+ textImageFormat.setWidth(RscMgr::settingHandler()->headerWidth());
+ textImageFormat.setHeight(RscMgr::settingHandler()->headerHeight());
+
+ QTextBlockFormat textBlockFormat;
+ textBlockFormat.setAlignment(RscMgr::settingHandler()->headerAlignment());
+
+ curser.setBlockFormat(textBlockFormat);
+
+ curser.insertImage(textImageFormat);
+
+ curser.insertBlock();
+ curser.setBlockFormat(QTextBlockFormat());
+ }
+
+ curser.insertHtml(printOption->preamble());
+
+ QTextTableFormat tableFormat;
+ tableFormat.setAlignment(Qt::AlignCenter);
+ tableFormat.setBorder(1);
+ tableFormat.setBorderBrush(Qt::lightGray);
+ tableFormat.setBorderStyle(QTextFrameFormat::BorderStyle_Double);
+ tableFormat.setCellPadding(3);
+ tableFormat.setCellSpacing(1);
+ tableFormat.setMargin(3);
+ tableFormat.setWidth(doc.textWidth());
+ tableFormat.setHeaderRowCount(1);
+
+ //the addition by one is for the vertical header.
+ const int tableColumnCount = model->columnCount() - printOption->hiddenColumnCount() + 1;
+
+ QVector textLengthVector(tableColumnCount);
+ textLengthVector.replace(RscMgr::dir() == Qt::RightToLeft ? tableColumnCount - 1 : 0, QTextLength(QTextLength::PercentageLength, 5));
+ tableFormat.setColumnWidthConstraints(textLengthVector);
+
+ QTextTable *textTable = curser.insertTable(1, tableColumnCount, tableFormat);
+
+ QTextCharFormat cornerCellFormat;
+ cornerCellFormat.setBackground(Qt::black);
+
+ QTextCharFormat headerCellFormat;
+ headerCellFormat.setBackground(Qt::darkGray);
+ headerCellFormat.setForeground(Qt::white);
+ headerCellFormat.setFontFamily(RscMgr::settingHandler()->tableFontFamily());
+ headerCellFormat.setFontPointSize(RscMgr::settingHandler()->tableFontSize().toInt() + 4);
+
+ QTextCharFormat sectionCellFormat;
+ sectionCellFormat.setBackground(Qt::lightGray);
+ sectionCellFormat.setForeground(Qt::white);
+ sectionCellFormat.setFontFamily(RscMgr::settingHandler()->tableFontFamily());
+ sectionCellFormat.setFontPointSize(RscMgr::settingHandler()->tableFontSize().toInt() + 2);
+
+ QTextCharFormat tableCellFormat;
+ tableCellFormat.setFontFamily(RscMgr::settingHandler()->tableFontFamily());
+ tableCellFormat.setFontPointSize(RscMgr::settingHandler()->tableFontSize().toInt());
+ tableCellFormat.setForeground(QColor(RscMgr::settingHandler()->tableFontColor()));
+
+ //filling the corner in black
+ if (RscMgr::dir() == Qt::RightToLeft)
+ textTable->cellAt(0, textTable->columns() - 1).setFormat(cornerCellFormat);
+ else
+ textTable->cellAt(0, 0).setFormat(cornerCellFormat);
+
+ // textTable column index, beginning at 1 due to the existence of id column
+ int y = 1;
+ for (int j = 0; j < model->columnCount(); ++j) {
+ if (printOption->isColumnHidden(j))
+ continue;
+
+ QTextTableCell cell = textTable->cellAt(0, RscMgr::dir() == Qt::RightToLeft ? textTable->columns() - y - 1 : y);
+ cell.setFormat(headerCellFormat);
+ cell.firstCursorPosition().insertText(model->headerData(j, Qt::Horizontal).toString());
+ ++y;
+ }
+
+ if (printOption->currentAggregativeColumn() >= 0)
+ model->sort(printOption->currentAggregativeColumn(), Qt::AscendingOrder);
+ else
+ model->sort(0, Qt::AscendingOrder);
+
+ QVariant lastValue;
+ for (int i = 0, x = 1; i < model->rowCount(); ++i, ++x) {
+ if (printOption->isRowHidden(model->index(i, 0).data().toInt())) {
+ --x;
+ continue;
+ }
+
+ if (printOption->currentAggregativeColumn() >= 0) {
+ const QString &entry = model->index(i, printOption->currentAggregativeColumn()).data().toString();
+ if (lastValue != entry) {
+ if (printOption->isAggregationEntryHidden(entry)) {
+ --x;
+ continue;
+ }
+
+ lastValue = entry;
+ textTable->insertRows(x, 1);
+ textTable->mergeCells(x, 0, 1, textTable->columns());
+ textTable->cellAt(x, 0).setFormat(sectionCellFormat);
+ textTable->cellAt(x, 0).firstCursorPosition().insertText(lastValue.toString());
+ ++x;
+ }
+ }
+
+ textTable->insertRows(x, 1);
+ QTextTableCell cell = textTable->cellAt(x, RscMgr::dir() == Qt::RightToLeft ? textTable->columns() - 1 : 0);
+ cell.setFormat(headerCellFormat);
+ cell.firstCursorPosition().insertText(model->headerData(i, Qt::Vertical).toString());
+
+ int y = 1; //textTable column index.
+ for (int j = 0; j < model->columnCount(); ++j) {
+ if (printOption->isColumnHidden(j))
+ continue;
+
+
+ textTable->cellAt(x, RscMgr::dir() == Qt::RightToLeft ? textTable->columns() - y - 1 : y)
+ .firstCursorPosition()
+ .insertText(model->index(i, j).data().toString(), tableCellFormat);
+ ++y;
+ }
+ }
+
+ curser.movePosition(QTextCursor::End);
+ curser.insertBlock();
+
+ curser.insertHtml(printOption->commentary());
+
+ doc.print(printer);
+}
diff --git a/handlers/printerhandler.h b/handlers/printerhandler.h
new file mode 100644
index 0000000..d015383
--- /dev/null
+++ b/handlers/printerhandler.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef PRINTERHANDLER_H
+#define PRINTERHANDLER_H
+
+#include
+#include
+
+class QAbstractItemModel;
+
+class PrintOption;
+
+class PrinterHandler : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit PrinterHandler(QObject *parent = 0);
+
+ static PrinterHandler *singleton();
+
+ QPrinter *nativePrinter();
+
+ QPrinter *previewPrinter();
+
+ QPrinter *settingPreviewPrinter();
+
+ static void print(QAbstractItemModel *model, PrintOption *printOption, QPrinter *printer);
+
+private slots:
+ void initialize();
+
+private:
+ QPrinter m_nativePrinter;
+ QPrinter m_previewPrinter;
+ QPrinter m_settingPreviewPrinter;
+};
+
+#endif // PRINTERHANDLER_H
diff --git a/handlers/settinghandler.cpp b/handlers/settinghandler.cpp
new file mode 100644
index 0000000..fdb7c2c
--- /dev/null
+++ b/handlers/settinghandler.cpp
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "settinghandler.h"
+
+#include "settingenumeration.h"
+#include "resourcemanager.h"
+
+#include
+
+SettingHandler::SettingHandler(QObject *parent) :
+ QObject(parent)
+{
+ m_map.insert(NS_Setting::InterfaceLanguage, "app/language");
+
+ m_map.insert(NS_Setting::DatabasePath, "database/path");
+
+ m_map.insert(NS_Setting::PrinterName, "printer/name");
+ m_map.insert(NS_Setting::PrinterPaperSize, "printer/paper-size");
+ m_map.insert(NS_Setting::PrinterColorMode, "printer/color-mode");
+ m_map.insert(NS_Setting::PrinterOrientation, "printer/orientation");
+ m_map.insert(NS_Setting::PrinterLeftMargin, "report/margin-left");
+ m_map.insert(NS_Setting::PrinterTopMargin, "report/margin-top");
+ m_map.insert(NS_Setting::PrinterRightMargin, "report/margin-right");
+ m_map.insert(NS_Setting::PrinterBottomMargin, "report/margin-bottom");
+
+ m_map.insert(NS_Setting::HeaderType, "report/header-type");
+ m_map.insert(NS_Setting::HeaderImagePath, "report/header-path");
+ m_map.insert(NS_Setting::HeaderWidth, "report/header-width");
+ m_map.insert(NS_Setting::HeaderHeight, "report/header-height");
+ m_map.insert(NS_Setting::HeaderAlignment, "report/header-alignment");
+
+ m_map.insert(NS_Setting::PreambleFontFamily, "report/preamble/font-family");
+ m_map.insert(NS_Setting::PreambleFontSize, "report/preamble/font-size");
+ m_map.insert(NS_Setting::PreambleFontColor, "report/preamble/font-color");
+
+ m_map.insert(NS_Setting::CommentaryFontFamily, "report/commentary/font-family");
+ m_map.insert(NS_Setting::CommentaryFontSize, "report/commentary/font-size");
+ m_map.insert(NS_Setting::CommentaryFontColor, "report/commentary/font-color");
+
+ m_map.insert(NS_Setting::TableFontFamily, "report/table/font-family");
+ m_map.insert(NS_Setting::TableFontSize, "report/table/font-size");
+ m_map.insert(NS_Setting::TableFontColor, "report/table/-font-color");
+}
+
+SettingHandler *SettingHandler::singleton()
+{
+ static SettingHandler *settingHandler = NULL;
+
+ if (!settingHandler)
+ settingHandler = new SettingHandler(qApp);
+
+ return settingHandler;
+}
+
+void SettingHandler::setValue(NS_Setting::SettingEntry key, const QVariant &value)
+{
+ m_settings.setValue(m_map.value(key), value);
+
+ emit settingChanged();
+}
+
+QVariant SettingHandler::value(NS_Setting::SettingEntry key, const QVariant &defaultValue) const
+{
+ return m_settings.value(m_map.value(key), defaultValue);
+}
+
+void SettingHandler::setInterfaceLanguage(int lang)
+{
+ setValue(NS_Setting::InterfaceLanguage, lang);
+}
+
+NS_Language::Language SettingHandler::interfaceLanguage() const
+{
+ return static_cast(value(NS_Setting::InterfaceLanguage, NS_Language::Arabic).toInt());
+}
+
+void SettingHandler::setDatabasePath(const QString &path)
+{
+ setValue(NS_Setting::DatabasePath, path);
+}
+
+QString SettingHandler::databasePath() const
+{
+ return value(NS_Setting::DatabasePath, "./data.fdb").toString();
+}
+
+void SettingHandler::setPrinterName(const QString &name)
+{
+ setValue(NS_Setting::PrinterName, name);
+}
+
+QString SettingHandler::printerName() const
+{
+ return value(NS_Setting::PrinterName, QString()).toString();
+}
+
+void SettingHandler::setPrinterPageSize(int size)
+{
+ setValue(NS_Setting::PrinterPaperSize, size);
+}
+
+QPrinter::PageSize SettingHandler::printerPageSize() const
+{
+ return static_cast(value(NS_Setting::PrinterPaperSize, QPrinter::A4).toInt());
+}
+
+void SettingHandler::setPrinterOrientation(int orientation)
+{
+ setValue(NS_Setting::PrinterOrientation, orientation);
+}
+
+QPrinter::Orientation SettingHandler::printerOrientation() const
+{
+ return static_cast(value(NS_Setting::PrinterOrientation, QPrinter::Portrait).toInt());
+}
+
+void SettingHandler::setPrinterColorMode(int mode)
+{
+ setValue(NS_Setting::PrinterColorMode, mode);
+}
+
+QPrinter::ColorMode SettingHandler::printerColorMode() const
+{
+ return static_cast(value(NS_Setting::PrinterColorMode, QPrinter::Color).toInt());
+}
+
+void SettingHandler::setPrinterLeftMargin(int margin)
+{
+ setValue(NS_Setting::PrinterLeftMargin, margin);
+}
+
+int SettingHandler::printerLeftMargin() const
+{
+ return value(NS_Setting::PrinterLeftMargin, 0).toInt();
+}
+
+void SettingHandler::setPrinterTopMargin(int margin)
+{
+ setValue(NS_Setting::PrinterTopMargin, margin);
+}
+
+int SettingHandler::printerTopMargin() const
+{
+ return value(NS_Setting::PrinterTopMargin, 0).toInt();
+}
+
+void SettingHandler::setPrinterRightMargin(int margin)
+{
+ setValue(NS_Setting::PrinterRightMargin, margin);
+}
+
+int SettingHandler::printerRightMargin() const
+{
+ return value(NS_Setting::PrinterRightMargin, 0).toInt();
+}
+
+void SettingHandler::setPrinterBottomMargin(int margin)
+{
+ setValue(NS_Setting::PrinterBottomMargin, margin);
+}
+
+int SettingHandler::printerBottomMargin() const
+{
+ return value(NS_Setting::PrinterBottomMargin, 0).toInt();
+}
+
+void SettingHandler::setHeaderType(int type)
+{
+ setValue(NS_Setting::HeaderType, type);
+}
+
+NS_HeaderType::HeaderType SettingHandler::headerType() const
+{
+ return static_cast(value(NS_Setting::HeaderType, NS_HeaderType::None).toInt());
+}
+
+void SettingHandler::setHeaderImagePath(const QString &path)
+{
+ setValue(NS_Setting::HeaderImagePath, path);
+}
+
+QString SettingHandler::headerImagePath() const
+{
+ return value(NS_Setting::HeaderImagePath, QString("...")).toString();
+}
+
+void SettingHandler::setHeaderWidth(int width)
+{
+ setHeaderWidthMM(double(width) / RscMgr::printHandler()->previewPrinter()->width() * RscMgr::printHandler()->previewPrinter()->widthMM());
+}
+
+int SettingHandler::headerWidth() const
+{
+ return double(headerWidthMM()) / RscMgr::printHandler()->previewPrinter()->widthMM() * RscMgr::printHandler()->previewPrinter()->width();
+}
+
+void SettingHandler::setHeaderHeight(int height)
+{
+ setHeaderHeightMM(double(height) / RscMgr::printHandler()->previewPrinter()->height() * RscMgr::printHandler()->previewPrinter()->heightMM());
+}
+
+int SettingHandler::headerHeight() const
+{
+ return double(headerHeightMM()) / RscMgr::printHandler()->previewPrinter()->heightMM() * RscMgr::printHandler()->previewPrinter()->height();
+}
+
+void SettingHandler::setHeaderWidthMM(int width)
+{
+ setValue(NS_Setting::HeaderWidth, width);
+}
+
+int SettingHandler::headerWidthMM() const
+{
+ return value(NS_Setting::HeaderWidth, 50).toInt();
+}
+
+void SettingHandler::setHeaderHeightMM(int height)
+{
+ setValue(NS_Setting::HeaderHeight, height);
+}
+
+int SettingHandler::headerHeightMM() const
+{
+ return value(NS_Setting::HeaderHeight, 20).toInt();
+}
+
+void SettingHandler::setHeaderAlignment(int align)
+{
+ setValue(NS_Setting::HeaderAlignment, align);
+}
+
+Qt::Alignment SettingHandler::headerAlignment() const
+{
+ return static_cast(value(NS_Setting::HeaderAlignment, Qt::AlignHCenter).toInt());
+}
+
+void SettingHandler::setPreambleFontFamily(const QString &fontFamily)
+{
+ setValue(NS_Setting::PreambleFontFamily, fontFamily);
+}
+
+QString SettingHandler::preambleFontFamily() const
+{
+ return value(NS_Setting::PreambleFontFamily, "sakkal majalla").toString();
+}
+
+void SettingHandler::setPreambleFontSize(const QString &fontSize)
+{
+ setValue(NS_Setting::PreambleFontSize, fontSize);
+}
+
+QString SettingHandler::preambleFontSize() const
+{
+ return value(NS_Setting::PreambleFontSize, "14").toString();
+}
+
+void SettingHandler::setPreambleFontColor(const QString &fontColor)
+{
+ setValue(NS_Setting::PreambleFontColor, fontColor);
+}
+
+QString SettingHandler::preambleFontColor() const
+{
+ return value(NS_Setting::PreambleFontColor, QColor(Qt::black).name(QColor::HexRgb)).toString();
+}
+
+void SettingHandler::setCommentaryFontFamily(const QString &fontFamily)
+{
+ setValue(NS_Setting::CommentaryFontFamily, fontFamily);
+}
+
+QString SettingHandler::commentaryFontFamily() const
+{
+ return value(NS_Setting::CommentaryFontFamily, "sakkal majalla").toString();
+}
+
+void SettingHandler::setCommentaryFontSize(const QString &fontSize)
+{
+ setValue(NS_Setting::CommentaryFontSize, fontSize);
+}
+
+QString SettingHandler::commentaryFontSize() const
+{
+ return value(NS_Setting::CommentaryFontSize, "14").toString();
+}
+
+void SettingHandler::setCommentaryFontColor(const QString &fontColor)
+{
+ setValue(NS_Setting::CommentaryFontColor, fontColor);
+}
+
+QString SettingHandler::commentaryFontColor() const
+{
+ return value(NS_Setting::CommentaryFontColor, QColor(Qt::black).name(QColor::HexRgb)).toString();
+}
+
+void SettingHandler::setTableFontFamily(const QString &fontFamily)
+{
+ setValue(NS_Setting::TableFontFamily, fontFamily);
+}
+
+QString SettingHandler::tableFontFamily() const
+{
+ return value(NS_Setting::TableFontFamily, "sakkal majalla").toString();
+}
+
+void SettingHandler::setTableFontSize(const QString &fontSize)
+{
+ setValue(NS_Setting::TableFontSize, fontSize);
+}
+
+QString SettingHandler::tableFontSize() const
+{
+ return value(NS_Setting::TableFontSize, "14").toString();
+}
+
+void SettingHandler::setTableFontColor(const QString &fontColor)
+{
+ setValue(NS_Setting::TableFontColor, fontColor);
+}
+
+QString SettingHandler::tableFontColor() const
+{
+ return value(NS_Setting::TableFontColor, QColor(Qt::black).name(QColor::HexRgb)).toString();
+}
diff --git a/handlers/settinghandler.h b/handlers/settinghandler.h
new file mode 100644
index 0000000..0c208e1
--- /dev/null
+++ b/handlers/settinghandler.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef SETTINGHANDLER_H
+#define SETTINGHANDLER_H
+
+#include
+#include
+#include
+
+#include "generalenumeration.h"
+#include "settingenumeration.h"
+
+class SettingHandler : public QObject
+{
+ Q_OBJECT
+
+public:
+ static SettingHandler *singleton();
+
+public slots:
+ void setDatabasePath(const QString &);
+ QString databasePath() const;
+
+ void setInterfaceLanguage(int);
+ NS_Language::Language interfaceLanguage() const;
+
+ void setPrinterName(const QString &);
+ QString printerName() const;
+
+ void setPrinterPageSize(int);
+ QPrinter::PageSize printerPageSize() const;
+
+ void setPrinterOrientation(int);
+ QPrinter::Orientation printerOrientation() const;
+
+ void setPrinterColorMode(int);
+ QPrinter::ColorMode printerColorMode() const;
+
+ void setPrinterTopMargin(int);
+ int printerTopMargin() const;
+
+ void setPrinterBottomMargin(int);
+ int printerBottomMargin() const;
+
+ void setPrinterRightMargin(int);
+ int printerRightMargin() const;
+
+ void setPrinterLeftMargin(int);
+ int printerLeftMargin() const;
+
+ void setHeaderType(int);
+ NS_HeaderType::HeaderType headerType() const;
+
+ void setHeaderImagePath(const QString &);
+ QString headerImagePath() const;
+
+ void setHeaderWidth(int);
+ int headerWidth() const;
+
+ void setHeaderHeight(int);
+ int headerHeight() const;
+
+ void setHeaderWidthMM(int);
+ int headerWidthMM() const;
+
+ void setHeaderHeightMM(int);
+ int headerHeightMM() const;
+
+ void setHeaderAlignment(int);
+ Qt::Alignment headerAlignment() const;
+
+ void setPreambleFontFamily(const QString &);
+ QString preambleFontFamily() const;
+
+ void setPreambleFontSize(const QString &);
+ QString preambleFontSize() const;
+
+ void setPreambleFontColor(const QString &);
+ QString preambleFontColor() const;
+
+ void setCommentaryFontFamily(const QString &);
+ QString commentaryFontFamily() const;
+
+ void setCommentaryFontSize(const QString &);
+ QString commentaryFontSize() const;
+
+ void setCommentaryFontColor(const QString &);
+ QString commentaryFontColor() const;
+
+ void setTableFontFamily(const QString &);
+ QString tableFontFamily() const;
+
+ void setTableFontSize(const QString &);
+ QString tableFontSize() const;
+
+ void setTableFontColor(const QString &);
+ QString tableFontColor() const;
+
+signals:
+ void settingChanged();
+
+private:
+ explicit SettingHandler(QObject *parent = 0);
+
+ void setValue(NS_Setting::SettingEntry key, const QVariant &value);
+ QVariant value(NS_Setting::SettingEntry key, const QVariant &defaultValue = QVariant()) const;
+
+ QMap m_map;
+ QSettings m_settings;
+};
+
+#endif // SETTINGHANDLER_H
diff --git a/handlers/translatorhandler.cpp b/handlers/translatorhandler.cpp
new file mode 100644
index 0000000..2165921
--- /dev/null
+++ b/handlers/translatorhandler.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "translatorhandler.h"
+
+#include "resourcemanager.h"
+
+#include
+
+TranslatorHandler::TranslatorHandler(QObject *parent) :
+ QObject(parent),
+ m_translator(new QTranslator(this))
+{
+ qApp->installTranslator(m_translator);
+}
+
+TranslatorHandler *TranslatorHandler::singleton()
+{
+ static TranslatorHandler *translatorHandler = NULL;
+
+ if (!translatorHandler)
+ translatorHandler = new TranslatorHandler(qApp);
+
+ return translatorHandler;
+}
+
+void TranslatorHandler::translate(NS_Language::Language lang)
+{
+ switch (lang) {
+ case NS_Language::Arabic:
+ m_translator->load("ar");
+ break;
+ case NS_Language::English:
+ m_translator->load("en");
+ break;
+ default:
+ break;
+ }
+
+ emit languageChanged();
+}
diff --git a/handlers/translatorhandler.h b/handlers/translatorhandler.h
new file mode 100644
index 0000000..0393bd7
--- /dev/null
+++ b/handlers/translatorhandler.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef TRANSLATORHANDLER_H
+#define TRANSLATORHANDLER_H
+
+#include
+#include
+
+#include "generalenumeration.h"
+
+class TranslatorHandler : public QObject
+{
+ Q_OBJECT
+
+public:
+ static TranslatorHandler *singleton();
+
+ void translate(NS_Language::Language);
+
+signals:
+ void languageChanged() const;
+
+private:
+ explicit TranslatorHandler(QObject *parent = 0);
+
+ QTranslator *m_translator;
+};
+
+#endif // TRANSLATORHANDLER_H
diff --git a/installer.nsi b/installer.nsi
new file mode 100644
index 0000000..4b44069
--- /dev/null
+++ b/installer.nsi
@@ -0,0 +1,175 @@
+;Furqan Installer
+;--------------------------------
+;Include Modern UI
+
+ !include "MUI2.nsh"
+
+;--------------------------------
+;General
+
+ ;Name and file
+ Name "Furqan"
+ OutFile "Furqan v1.0.0.exe"
+
+ ;Default installation folder
+ InstallDir "D:\Furqan"
+
+ ;Get installation folder from registry if available
+ InstallDirRegKey HKCU "Software\ShamSoft\Furqan" ""
+
+ ;Request application privileges for Windows Vista
+ RequestExecutionLevel admin
+
+;--------------------------------
+;Interface Settings
+
+ !define MUI_ABORTWARNING
+
+;--------------------------------
+;Language Selection Dialog Settings
+
+ ;Remember the installer language
+ !define MUI_LANGDLL_REGISTRY_ROOT "HKCU"
+ !define MUI_LANGDLL_REGISTRY_KEY "Software\ShamSoft\Furqan"
+ !define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language"
+
+;--------------------------------
+;Pages
+
+ !insertmacro MUI_PAGE_LICENSE "license.txt"
+ !insertmacro MUI_PAGE_DIRECTORY
+ !insertmacro MUI_PAGE_INSTFILES
+
+ !insertmacro MUI_UNPAGE_CONFIRM
+ !insertmacro MUI_UNPAGE_INSTFILES
+
+;--------------------------------
+;Languages
+
+ !insertmacro MUI_LANGUAGE "ARABIC" ;first language is the default language
+ !insertmacro MUI_LANGUAGE "ENGLISH"
+
+;--------------------------------
+;Reserve Files
+
+ ;If you are using solid compression, files that are required before
+ ;the actual installation should be stored first in the data block,
+ ;because this will make your installer start faster.
+
+ !insertmacro MUI_RESERVEFILE_LANGDLL
+
+;--------------------------------
+;Installer Sections
+
+Section Sec
+
+ SetOutPath "$INSTDIR"
+
+ ;ADD YOUR OWN FILES HERE...
+
+ CreateDirectory $INSTDIR\intl
+ SetOutPath $INSTDIR\intl
+ File "intl\fbintl.conf"
+ File "intl\fbintl.dll"
+
+ CreateDirectory $INSTDIR\platforms
+ SetOutPath $INSTDIR\platforms
+ File "platforms\qwindows.dll"
+
+ CreateDirectory $INSTDIR\sqldrivers
+ SetOutPath $INSTDIR\sqldrivers
+ File "sqldrivers\qsqlibase.dll"
+
+ CreateDirectory $INSTDIR\printsupport
+ SetOutPath $INSTDIR\printsupport
+ File "printsupport\windowsprintersupport.dll"
+
+ SetOutPath $INSTDIR
+
+ ; Put files there
+
+ File "Furqan.exe"
+ File "ar.qm"
+ File "en.qm"
+ File "license.txt"
+ File "data.fdb"
+ File "fbclient.dll"
+ File "firebird.msg"
+ File "ib_util.dll"
+ File "icudt30.dll"
+ File "icudt52.dll"
+ File "icuin30.dll"
+ File "icuin52.dll"
+ File "icuuc30.dll"
+ File "icuuc52.dll"
+ File "libgcc_s_dw2-1.dll"
+ File "libGLESv2.dll"
+ File "libstdc++-6.dll"
+ File "libwinpthread-1.dll"
+ File "Microsoft.VC80.CRT.manifest"
+ File "msvcp80.dll"
+ File "msvcr80.dll"
+ File "Qt5Core.dll"
+ File "Qt5Gui.dll"
+ File "Qt5PrintSupport.dll"
+ File "Qt5Sql.dll"
+ File "Qt5Widgets.dll"
+
+ ;Store installation folder
+ WriteRegStr HKCU "Software\ShamSoft\Furqan" "" $INSTDIR
+
+ ;Add an entry to Add/Remove Programs.
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Furqan" "DisplayName" "Furqan v1.0.0"
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Furqan" "UninstallString" '"$INSTDIR\uninstall.exe"'
+ WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Furqan" "NoModify" 1
+ WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Furqan" "NoRepair" 1
+ WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Furqan" "VersionMajor" 1
+ WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Furqan" "VersionMinor" 0
+
+ ;Create uninstaller
+ WriteUninstaller "$INSTDIR\uninstall.exe"
+
+ CreateDirectory "$SMPROGRAMS\Furqan"
+ CreateShortCut "$SMPROGRAMS\Furqan\uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
+ CreateShortCut "$SMPROGRAMS\Furqan\Furqan v1.0.0.lnk" "$INSTDIR\Furqan.exe" "" "$INSTDIR\Furqan.exe" 0
+ CreateShortCut "$DESKTOP\Furqan v1.0.0.lnk" "$INSTDIR\Furqan.exe" "" "$INSTDIR\Furqan.exe" 0
+
+SectionEnd
+
+;--------------------------------
+;Installer Functions
+
+Function .onInit
+
+ !insertmacro MUI_LANGDLL_DISPLAY
+
+FunctionEnd
+
+;--------------------------------
+;Uninstaller Section
+
+Section "Uninstall"
+
+ ; Deleting the program's files and directories
+
+ RMDir /r "$INSTDIR"
+
+ DeleteRegKey /ifempty HKCU "Software\ShamSoft\Furqan"
+
+ ; Remove shortcuts, if any
+ Delete "$SMPROGRAMS\Furqan\*.*"
+ Delete "$DESKTOP\Furqan v1.0.0.lnk"
+
+ ; Remove the program's entry from add/remove programs.
+ DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Furqan"
+
+SectionEnd
+
+;--------------------------------
+;Uninstaller Functions
+
+Function un.onInit
+
+ !insertmacro MUI_UNGETLANGUAGE
+
+FunctionEnd
\ No newline at end of file
diff --git a/interfaces/classwidget.ui b/interfaces/classwidget.ui
new file mode 100644
index 0000000..9c0a6e9
--- /dev/null
+++ b/interfaces/classwidget.ui
@@ -0,0 +1,40 @@
+
+
+ ClassWidget
+
+
+
+ 0
+ 0
+ 256
+ 192
+
+
+
+
+ 3
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+ QAbstractItemView::SingleSelection
+
+
+
+
+
+
+
+
diff --git a/interfaces/competitionwidget.ui b/interfaces/competitionwidget.ui
new file mode 100644
index 0000000..01de7c6
--- /dev/null
+++ b/interfaces/competitionwidget.ui
@@ -0,0 +1,40 @@
+
+
+ CompetitionWidget
+
+
+
+ 0
+ 0
+ 256
+ 192
+
+
+
+
+ 3
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+ QAbstractItemView::SingleSelection
+
+
+
+
+
+
+
+
diff --git a/interfaces/competitorwidget.ui b/interfaces/competitorwidget.ui
new file mode 100644
index 0000000..4567061
--- /dev/null
+++ b/interfaces/competitorwidget.ui
@@ -0,0 +1,91 @@
+
+
+ CompetitorWidget
+
+
+
+ 0
+ 0
+ 524
+ 215
+
+
+
+
+ 3
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+
+
+
+
+ Competition
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+ false
+
+
+ QAbstractItemView::SelectRows
+
+
+
+
+
+
+
+
+
+
+ Competitor
+
+
+
+
+
+
+ Qt::StrongFocus
+
+
+ QAbstractItemView::SingleSelection
+
+
+ QAbstractItemView::SelectRows
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/interfaces/coursewidget.ui b/interfaces/coursewidget.ui
new file mode 100644
index 0000000..d172dad
--- /dev/null
+++ b/interfaces/coursewidget.ui
@@ -0,0 +1,40 @@
+
+
+ CourseWidget
+
+
+
+ 0
+ 0
+ 256
+ 192
+
+
+
+
+ 3
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+ QAbstractItemView::SingleSelection
+
+
+
+
+
+
+
+
diff --git a/interfaces/employeewidget.ui b/interfaces/employeewidget.ui
new file mode 100644
index 0000000..842e7aa
--- /dev/null
+++ b/interfaces/employeewidget.ui
@@ -0,0 +1,91 @@
+
+
+ EmployeeWidget
+
+
+
+ 0
+ 0
+ 524
+ 215
+
+
+
+
+ 3
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+
+
+
+
+ Job
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+ false
+
+
+ QAbstractItemView::SelectRows
+
+
+
+
+
+
+
+
+
+
+ Employee
+
+
+
+
+
+
+ Qt::StrongFocus
+
+
+ QAbstractItemView::SingleSelection
+
+
+ QAbstractItemView::SelectRows
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/interfaces/jobwidget.ui b/interfaces/jobwidget.ui
new file mode 100644
index 0000000..0cc266f
--- /dev/null
+++ b/interfaces/jobwidget.ui
@@ -0,0 +1,40 @@
+
+
+ JobWidget
+
+
+
+ 0
+ 0
+ 256
+ 192
+
+
+
+
+ 3
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+ QAbstractItemView::SingleSelection
+
+
+
+
+
+
+
+
diff --git a/interfaces/mainwidget.ui b/interfaces/mainwidget.ui
new file mode 100644
index 0000000..91bbc7c
--- /dev/null
+++ b/interfaces/mainwidget.ui
@@ -0,0 +1,538 @@
+
+
+ MainWidget
+
+
+ QPushButton:flat {
+ border: none;
+ background: transparent;
+ padding: 3px;
+}
+QPushButton:flat:hover {
+ border: 1px solid lightgray;
+}
+QPushButton:flat:checked {
+ border: 1px solid #01bccd;
+ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,
+ stop:0 #616161, stop: 0.5 #505050,
+ stop: 0.6 #434343, stop:1 #656565);
+}
+
+QToolBar {
+ spacing: 3px;
+}
+
+QTableView::item:selected:!active {
+ background: qlineargradient(spread:reflect, x1:0.539, y1:0, x2:0.489, y2:1, stop:0 rgba(150, 150, 0, 100), stop:1 rgba(200, 200, 0, 100));
+ color: black;
+}
+QTableView::item:selected:active {
+ background: qlineargradient(spread:reflect, x1:0.539, y1:0, x2:0.489, y2:1, stop:0 rgba(150, 150, 0, 200), stop:1 rgba(200, 200, 0, 200));
+ color: black;
+}
+QTableView::item:hover {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #EAEAEA, stop: 1 #DDDDDD);
+}
+QTableView::focus {
+ background-color: rgb(255, 255, 255);
+ border: 2px solid #ffff00;
+}
+QTableView::!focus {
+ background-color: rgb(240, 240, 240);
+ border: 1px solid rgb(0, 0, 0);
+}
+
+QHeaderView::section {
+ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,
+ stop:0 #616161, stop: 0.5 #505050,
+ stop: 0.6 #434343, stop:1 #656565);
+ color: white;
+ padding: 6px;
+ border: 1px solid #6c6c6c;
+}
+
+QHeaderView::section:checked:vertical
+{
+ background-color: white;
+ color: black;
+}
+
+QListView {
+ background: lightgray;
+ color: black;
+ border: 1px solid black;
+}
+QListView::item:selected:active, QListView::item:selected:!active {
+/*
+ background: qlineargradient(spread:reflect, x1:0.539, y1:0, x2:0.489, y2:1, stop:0 rgba(125, 125, 0, 200), stop:1 rgba(175, 175, 0, 200));
+*/
+ background: darkgray;
+ color: white;
+}
+QListView::item, QListWidget::item {
+ padding: 4px;
+}
+
+QTabWidget::pane { /* The tab widget frame */
+ border: 2px solid #C2C7CB;
+}
+
+/* Style the tab using the tab sub-control. Note that
+ it reads QTabBar _not_ QTabWidget */
+QTabBar::tab {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #E1E1E1, stop: 0.4 #DDDDDD,
+ stop: 0.5 #D8D8D8, stop: 1.0 #D3D3D3);
+ border: 1px solid #C4C4C3;
+ border-bottom-color: #C2C7CB; /* same as the pane color */
+ border-top-left-radius: 6px;
+ border-bottom-left-radius: 6px;
+ min-width: 6ex;
+ min-height: 30ex;
+ padding: 2px;
+}
+
+QTabBar::tab:selected, QTabBar::tab:hover {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #fafafa, stop: 0.4 #f4f4f4,
+ stop: 0.5 #e7e7e7, stop: 1.0 #fafafa);
+}
+
+QTabBar::tab:selected {
+ border-color: #9B9B9B;
+ border-left-color: #C2C7CB; /* same as pane color */
+}
+
+QTabBar::tab:!selected {
+ margin-left: 3px; /* make non-selected tabs look smaller */
+}
+
+
+
+ 12
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
+
+
+ QFrame {
+background: gray;
+border: 1px solid black;
+margin: 0;
+padding: 0;
+}
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 10
+ 20
+
+
+
+
+
+
+
+
+ 14
+ 75
+ true
+
+
+
+ WhatsThisCursor
+
+
+ QPushButton {
+background: none;
+color: white;
+border: 0;
+margin: 0;
+padding: 0;
+}
+
+QPushButton:hover {
+background: none;
+color: yellow;
+border: 0;
+margin: 0;
+padding: 0;
+}
+
+
+ Furqan
+
+
+ true
+
+
+
+
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+ PointingHandCursor
+
+
+
+ :/minimize:/minimize
+
+
+
+ 24
+ 24
+
+
+
+ true
+
+
+
+
+
+
+ PointingHandCursor
+
+
+
+ :/exit:/exit
+
+
+
+ 24
+ 24
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+ 3
+
+
+
+
+
+ 0
+ 0
+
+
+
+ QFrame {
+background: gray;
+color: white;
+border: 1px solid black;
+margin: 0;
+padding: 0;
+show-decoration-selected: 1;
+}
+
+QListView::item:selected:active, QListView::item:selected:!active {
+ background:white;
+ color: black;
+}
+
+QListView::item:hover {
+/*
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #EAEBEC, stop: 1 #CCCCCC);
+ color: gray;
+
+QListView::item:hover, QListWidget::item:hover {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #EAEBEC, stop: 1 #CCCCCC);
+ color: gray;
+ padding: 0;
+}
+
+*/
+ border: 1px solid lightgray;
+}
+
+QListView::item {
+ padding: 4px;
+}
+
+
+
+
+
+
+ 12
+
+
+
+
+ QFrame {
+ background-color: lightgray;
+ border: 1px solid black;
+ padding: 1px;
+}
+QPushButton {
+ padding: 3px;
+ color: gray;
+}
+QPushButton:hover {
+ color: white;
+ border: 1px solid gray;
+}
+
+
+
+ QFrame::Box
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+ PointingHandCursor
+
+
+ &Add
+
+
+
+ :/table-add:/table-add
+
+
+
+ 32
+ 32
+
+
+
+ true
+
+
+
+
+
+
+ PointingHandCursor
+
+
+ &Modify
+
+
+
+ :/table-modify:/table-modify
+
+
+
+ 32
+ 32
+
+
+
+ true
+
+
+
+
+
+
+ PointingHandCursor
+
+
+ &Remove
+
+
+
+ :/table-remove:/table-remove
+
+
+
+ 32
+ 32
+
+
+
+ true
+
+
+
+
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+ PointingHandCursor
+
+
+ &Print
+
+
+
+ :/table-print:/table-print
+
+
+
+ 32
+ 32
+
+
+
+ true
+
+
+
+
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ minimizeButton
+ clicked()
+ MainWidget
+ showMinimized()
+
+
+ 670
+ 30
+
+
+ 5
+ 5
+
+
+
+
+ closeButton
+ clicked()
+ MainWidget
+ close()
+
+
+ 704
+ 30
+
+
+ 278
+ 10
+
+
+
+
+
diff --git a/interfaces/quranwidget.ui b/interfaces/quranwidget.ui
new file mode 100644
index 0000000..5e6215a
--- /dev/null
+++ b/interfaces/quranwidget.ui
@@ -0,0 +1,91 @@
+
+
+ QuranWidget
+
+
+
+ 0
+ 0
+ 524
+ 215
+
+
+
+
+ 3
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+
+
+
+
+ Student
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+ false
+
+
+ QAbstractItemView::SelectRows
+
+
+
+
+
+
+
+
+
+
+ Recital
+
+
+
+
+
+
+ Qt::StrongFocus
+
+
+ QAbstractItemView::SingleSelection
+
+
+ QAbstractItemView::SelectRows
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/interfaces/resultwidget.ui b/interfaces/resultwidget.ui
new file mode 100644
index 0000000..ff0d9ce
--- /dev/null
+++ b/interfaces/resultwidget.ui
@@ -0,0 +1,91 @@
+
+
+ ResultWidget
+
+
+
+ 0
+ 0
+ 524
+ 215
+
+
+
+
+ 3
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+
+
+
+
+ Course
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+ false
+
+
+ QAbstractItemView::SelectRows
+
+
+
+
+
+
+
+
+
+
+ Result
+
+
+
+
+
+
+ Qt::StrongFocus
+
+
+ QAbstractItemView::SingleSelection
+
+
+ QAbstractItemView::SelectRows
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/interfaces/settingwidget.ui b/interfaces/settingwidget.ui
new file mode 100644
index 0000000..2875aac
--- /dev/null
+++ b/interfaces/settingwidget.ui
@@ -0,0 +1,980 @@
+
+
+ SettingWidget
+
+
+
+ 0
+ 0
+ 621
+ 659
+
+
+
+
+ 3
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 70
+ 0
+
+
+
+
+ 70
+ 16777215
+
+
+
+ Qt::NoFocus
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+ 10
+
+
+ QListView::IconMode
+
+
+ -1
+
+
+
+ General
+
+
+
+ :/settings:/settings
+
+
+
+
+ Printer
+
+
+
+ :/printer:/printer
+
+
+
+
+ Report
+
+
+
+ :/report:/report
+
+
+
+
+
+
+
+ 0
+
+
+
+
+ 3
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+ Database
+
+
+
+
+
+ Path:
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+ ...
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+
+
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+ Backup
+
+
+
+ :/database-backup:/database-backup
+
+
+
+ 32
+ 32
+
+
+
+ true
+
+
+
+
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+ Change
+
+
+
+ :/database-connect:/database-connect
+
+
+
+ 32
+ 32
+
+
+
+ true
+
+
+
+
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+ Create
+
+
+
+ :/database-create:/database-create
+
+
+
+ 32
+ 32
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+ Language
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 527
+
+
+
+
+
+
+
+
+
+ 3
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+ Printer
+
+
+
+
+
+ Qt::LeftToRight
+
+
+
+
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+
+ Paper Size
+
+
+
+
+
+ A4
+
+
+
+
+
+
+ A5
+
+
+
+
+
+
+
+
+
+ Color Mode
+
+
+
+
+
+ Grayscale
+
+
+
+
+
+
+ Color
+
+
+
+
+
+
+
+
+
+ Orientation
+
+
+
+
+
+ Portrait
+
+
+
+
+
+
+ Landscape
+
+
+
+
+
+
+
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+ 3
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+
+
+ Margins
+
+
+
+
+
+ Top
+
+
+
+
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+ mm
+
+
+
+
+
+
+ Qt::Horizontal
+
+
+
+ 10
+ 10
+
+
+
+
+
+
+
+ Bottom
+
+
+
+
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+ mm
+
+
+
+
+
+
+ Qt::Horizontal
+
+
+
+ 10
+ 10
+
+
+
+
+
+
+
+ Right
+
+
+
+
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+ mm
+
+
+
+
+
+
+ Qt::Horizontal
+
+
+
+ 10
+ 10
+
+
+
+
+
+
+
+ Left
+
+
+
+
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+ mm
+
+
+
+
+
+
+
+
+
+ Header
+
+
+
+
+
+ None
+
+
+ true
+
+
+
+
+
+
+ Image
+
+
+
+
+
+
+
+
+
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 10
+ 20
+
+
+
+
+
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+ ...
+
+
+
+
+
+
+ ...
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+ Width
+
+
+
+
+
+
+ Qt::AlignCenter
+
+
+ 1
+
+
+ 333
+
+
+
+
+
+
+ mm
+
+
+
+
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+ Height
+
+
+
+
+
+
+ Qt::AlignCenter
+
+
+ 1
+
+
+
+
+
+
+ mm
+
+
+
+
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+ :/align-left:/align-left
+
+
+ true
+
+
+ true
+
+
+
+
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+ :/align-center:/align-center
+
+
+ true
+
+
+ true
+
+
+
+
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+ :/align-right:/align-right
+
+
+ true
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Qt::Vertical
+
+
+
+ 48
+ 98
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 1
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+ QFrame {
+background: gray;
+border: 1px solid black;
+margin: 0;
+padding: 0;
+}
+
+QPushButton {
+ padding: 3px;
+}
+
+QPushButton:hover {
+ color: white;
+ border: 1px solid lightgray;
+}
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+ Qt::Horizontal
+
+
+
+ 26
+ 20
+
+
+
+
+
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+ :/zoom-in:/zoom-in
+
+
+
+ 24
+ 24
+
+
+
+ true
+
+
+
+
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+ :/zoom-out:/zoom-out
+
+
+
+ 24
+ 24
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ settingListWidget
+ currentRowChanged(int)
+ stackedWidget
+ setCurrentIndex(int)
+
+
+ 731
+ 166
+
+
+ 677
+ 194
+
+
+
+
+ headerImageRadioButton
+ toggled(bool)
+ headerImageFrame
+ setVisible(bool)
+
+
+ 619
+ 233
+
+
+ 556
+ 249
+
+
+
+
+
diff --git a/interfaces/studentwidget.ui b/interfaces/studentwidget.ui
new file mode 100644
index 0000000..70b58a0
--- /dev/null
+++ b/interfaces/studentwidget.ui
@@ -0,0 +1,91 @@
+
+
+ StudentWidget
+
+
+
+ 0
+ 0
+ 524
+ 215
+
+
+
+
+ 3
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+
+
+
+
+ Class
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+ false
+
+
+ QAbstractItemView::SelectRows
+
+
+
+
+
+
+
+
+
+
+ Student
+
+
+
+
+
+
+ Qt::StrongFocus
+
+
+ QAbstractItemView::SingleSelection
+
+
+ QAbstractItemView::SelectRows
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/interfaces/teacherwidget.ui b/interfaces/teacherwidget.ui
new file mode 100644
index 0000000..68f7cd6
--- /dev/null
+++ b/interfaces/teacherwidget.ui
@@ -0,0 +1,57 @@
+
+
+ TeacherWidget
+
+
+
+ 0
+ 0
+ 258
+ 213
+
+
+
+
+ 3
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+
+
+ Teacher
+
+
+
+
+
+
+ Qt::StrongFocus
+
+
+ QAbstractItemView::SingleSelection
+
+
+ QAbstractItemView::SelectRows
+
+
+
+
+
+
+
+
+
+
diff --git a/interfaces/teachingwidget.ui b/interfaces/teachingwidget.ui
new file mode 100644
index 0000000..b49a57f
--- /dev/null
+++ b/interfaces/teachingwidget.ui
@@ -0,0 +1,91 @@
+
+
+ TeachingWidget
+
+
+
+ 0
+ 0
+ 524
+ 215
+
+
+
+
+ 3
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+
+
+
+
+ Teacher
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+ false
+
+
+ QAbstractItemView::SelectRows
+
+
+
+
+
+
+
+
+
+
+ Teaching
+
+
+
+
+
+
+ Qt::StrongFocus
+
+
+ QAbstractItemView::SingleSelection
+
+
+ QAbstractItemView::SelectRows
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..4d0da5f
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include
+#include
+
+#include "resourcemanager.h"
+#include "settingwidget.h"
+#include "mainwidget.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ QCoreApplication::setOrganizationName("ShamSoft");
+ QCoreApplication::setApplicationName("Furqan");
+
+ QSplashScreen *splashScreen = RscMgr::createSplashScreen();
+ splashScreen->show();
+
+ // To show the splash at the very beginning.
+ app.processEvents();
+
+ RscMgr::settingHandler();
+
+ RscMgr::translatorHandler()->translate(RscMgr::settingHandler()->interfaceLanguage());
+
+ //initializing the database,
+ //this prevents uninitialized access using static QSqlDatabase static methods.
+ RscMgr::databaseHandler();
+
+ if (!RscMgr::databaseHandler()->connection().isOpen()) {
+ RscMgr::issueMessage(QObject::tr("Program couldn't open the current database, please select another one"), false);
+
+ if (!SettingWidget::changeTheCurrentDatabase()) {
+ RscMgr::issueMessage(QObject::tr("Database is damaged, Program cannot proceed"), false);
+ app.quit();
+ }
+ }
+
+ //initializing the models,
+ RscMgr::modelHandler();
+
+ MainWidget *widget = new MainWidget;
+
+ app.setStyleSheet(widget->styleSheet());
+
+ widget->show();
+
+ splashScreen->finish(widget);
+
+ return app.exec();
+}
diff --git a/relations/abstractrelation.cpp b/relations/abstractrelation.cpp
new file mode 100644
index 0000000..6d04df3
--- /dev/null
+++ b/relations/abstractrelation.cpp
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "abstractrelation.h"
+
+AbstractRelation::AbstractRelation(QObject *parent) :
+ QObject(parent)
+{}
+
+AbstractRelation::~AbstractRelation()
+{}
diff --git a/relations/abstractrelation.h b/relations/abstractrelation.h
new file mode 100644
index 0000000..f372a87
--- /dev/null
+++ b/relations/abstractrelation.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef ABSTRACTRELATION_H
+#define ABSTRACTRELATION_H
+
+#include
+
+class AbstractRelation : public QObject
+{
+ Q_OBJECT
+
+public:
+ enum RelationType { Map, Sql };
+
+ explicit AbstractRelation(QObject *parent = 0);
+
+ virtual ~AbstractRelation();
+
+ virtual RelationType type() const = 0;
+
+ virtual QString forwardLookup(qlonglong key) const = 0;
+
+ virtual qlonglong backwardLookup(const QString &) const = 0;
+};
+
+#endif // ABSTRACTRELATION_H
diff --git a/relations/maprelation.cpp b/relations/maprelation.cpp
new file mode 100644
index 0000000..998c56f
--- /dev/null
+++ b/relations/maprelation.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "maprelation.h"
+
+#include
+
+MapRelation::MapRelation(const QMap *map, QObject *parent) :
+ AbstractRelation(parent),
+ m_map(map)
+{}
+
+QString MapRelation::forwardLookup(qlonglong key) const
+{
+ return m_map->value(key);
+}
+
+qlonglong MapRelation::backwardLookup(const QString &value) const
+{
+ return m_map->key(value);
+}
+
+AbstractRelation::RelationType MapRelation::type() const
+{
+ return Map;
+}
+const QMap *MapRelation::map() const
+{
+ return m_map;
+}
+
diff --git a/relations/maprelation.h b/relations/maprelation.h
new file mode 100644
index 0000000..f4ea2f1
--- /dev/null
+++ b/relations/maprelation.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef MAPRELATION_H
+#define MAPRELATION_H
+
+#include "abstractrelation.h"
+
+#include
+
+class MapRelation : public AbstractRelation
+{
+ Q_OBJECT
+
+public:
+ explicit MapRelation(const QMap *map, QObject *parent = 0);
+
+ QString forwardLookup(qlonglong key) const;
+
+ qlonglong backwardLookup(const QString &) const;
+
+ RelationType type() const;
+
+ const QMap *map() const;
+
+private:
+ const QMap *m_map;
+};
+
+#endif // MAPRELATION_H
diff --git a/relations/sqlrelation.cpp b/relations/sqlrelation.cpp
new file mode 100644
index 0000000..33207a5
--- /dev/null
+++ b/relations/sqlrelation.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "sqlrelation.h"
+
+#include
+
+SqlRelation::SqlRelation(const QSqlTableModel *remoteModel, int keyColumn, int displayColumn, QObject *parent) :
+ AbstractRelation(parent),
+ m_remoteModel(remoteModel),
+ m_keyColumn(keyColumn),
+ m_displayColumn(displayColumn)
+{}
+
+QString SqlRelation::forwardLookup(qlonglong key) const
+{
+ const QModelIndexList &list = m_remoteModel->match(m_remoteModel->index(0, m_keyColumn),
+ Qt::DisplayRole,
+ key,
+ 1,
+ Qt::MatchExactly);
+
+ if (list.isEmpty())
+ return QString();
+
+ return m_remoteModel->index(list.first().row(), m_displayColumn).data().toString();
+}
+
+qlonglong SqlRelation::backwardLookup(const QString &value) const
+{
+ const QModelIndexList &list = m_remoteModel->match(m_remoteModel->index(0, m_displayColumn),
+ Qt::DisplayRole,
+ value,
+ 1,
+ Qt::MatchExactly);
+
+ if (list.isEmpty())
+ return -1;
+
+ return m_remoteModel->index(list.first().row(), m_keyColumn).data().toLongLong();
+}
+
+AbstractRelation::RelationType SqlRelation::type() const
+{
+ return Sql;
+}
+
+const QSqlTableModel *SqlRelation::remoteModel() const
+{
+ return m_remoteModel;
+}
+
+int SqlRelation::keyColumn() const
+{
+ return m_keyColumn;
+}
+
+int SqlRelation::displayColumn() const
+{
+ return m_displayColumn;
+}
diff --git a/relations/sqlrelation.h b/relations/sqlrelation.h
new file mode 100644
index 0000000..7177f1d
--- /dev/null
+++ b/relations/sqlrelation.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef SQLRELATION_H
+#define SQLRELATION_H
+
+#include "abstractrelation.h"
+
+class QSqlTableModel;
+
+class SqlRelation : public AbstractRelation
+{
+ Q_OBJECT
+
+public:
+ explicit SqlRelation(const QSqlTableModel *remoteModel,
+ int keyColumn, int displayColumn, QObject *parent);
+
+ QString forwardLookup(qlonglong key) const;
+
+ qlonglong backwardLookup(const QString &) const;
+
+ RelationType type() const;
+
+ const QSqlTableModel *remoteModel() const;
+
+ int keyColumn() const;
+
+ int displayColumn() const;
+
+private:
+ const QSqlTableModel *m_remoteModel;
+
+ const int m_keyColumn;
+ const int m_displayColumn;
+};
+
+#endif // SQLRELATION_H
diff --git a/resource.qrc b/resource.qrc
new file mode 100644
index 0000000..b941b94
--- /dev/null
+++ b/resource.qrc
@@ -0,0 +1,31 @@
+
+
+ resources/printer.png
+ resources/zoom-in.png
+ resources/zoom-out.png
+ resources/report.png
+ resources/settings.png
+ resources/minimize.png
+ resources/empty.fdb
+ resources/database_backup.png
+ resources/database_connect.png
+ resources/database_create.png
+ resources/table_add.png
+ resources/table_modify.png
+ resources/table_print.png
+ resources/table_remove.png
+ resources/align-center.png
+ resources/align-left.png
+ resources/align-right.png
+ resources/bold.png
+ resources/italic.png
+ resources/underline.png
+ resources/exit.png
+ resources/close-ltr.png
+ resources/close-rtl.png
+ resources/emotion-happy.png
+ resources/emotion-sad.png
+ resources/splash-ar.png
+ resources/splash-en.png
+
+
diff --git a/resources/align-center.png b/resources/align-center.png
new file mode 100644
index 0000000..da6c110
Binary files /dev/null and b/resources/align-center.png differ
diff --git a/resources/align-left.png b/resources/align-left.png
new file mode 100644
index 0000000..db7de6a
Binary files /dev/null and b/resources/align-left.png differ
diff --git a/resources/align-right.png b/resources/align-right.png
new file mode 100644
index 0000000..c4cb852
Binary files /dev/null and b/resources/align-right.png differ
diff --git a/resources/bold.png b/resources/bold.png
new file mode 100644
index 0000000..9ccbcba
Binary files /dev/null and b/resources/bold.png differ
diff --git a/resources/close-ltr.png b/resources/close-ltr.png
new file mode 100644
index 0000000..f7e8ecf
Binary files /dev/null and b/resources/close-ltr.png differ
diff --git a/resources/close-rtl.png b/resources/close-rtl.png
new file mode 100644
index 0000000..f93f38a
Binary files /dev/null and b/resources/close-rtl.png differ
diff --git a/resources/database_backup.png b/resources/database_backup.png
new file mode 100644
index 0000000..5d24190
Binary files /dev/null and b/resources/database_backup.png differ
diff --git a/resources/database_connect.png b/resources/database_connect.png
new file mode 100644
index 0000000..a8b30e9
Binary files /dev/null and b/resources/database_connect.png differ
diff --git a/resources/database_create.png b/resources/database_create.png
new file mode 100644
index 0000000..19bbbd8
Binary files /dev/null and b/resources/database_create.png differ
diff --git a/resources/emotion-happy.png b/resources/emotion-happy.png
new file mode 100644
index 0000000..57ab60b
Binary files /dev/null and b/resources/emotion-happy.png differ
diff --git a/resources/emotion-sad.png b/resources/emotion-sad.png
new file mode 100644
index 0000000..b119182
Binary files /dev/null and b/resources/emotion-sad.png differ
diff --git a/resources/empty.fdb b/resources/empty.fdb
new file mode 100644
index 0000000..1a0cdf1
Binary files /dev/null and b/resources/empty.fdb differ
diff --git a/resources/exit.png b/resources/exit.png
new file mode 100644
index 0000000..fe5607a
Binary files /dev/null and b/resources/exit.png differ
diff --git a/resources/italic.png b/resources/italic.png
new file mode 100644
index 0000000..55e7de7
Binary files /dev/null and b/resources/italic.png differ
diff --git a/resources/minimize.png b/resources/minimize.png
new file mode 100644
index 0000000..a3fc7fe
Binary files /dev/null and b/resources/minimize.png differ
diff --git a/resources/printer.png b/resources/printer.png
new file mode 100644
index 0000000..0ebe0b0
Binary files /dev/null and b/resources/printer.png differ
diff --git a/resources/report.png b/resources/report.png
new file mode 100644
index 0000000..8722d00
Binary files /dev/null and b/resources/report.png differ
diff --git a/resources/settings.png b/resources/settings.png
new file mode 100644
index 0000000..5babead
Binary files /dev/null and b/resources/settings.png differ
diff --git a/resources/splash-ar.png b/resources/splash-ar.png
new file mode 100644
index 0000000..904a7d2
Binary files /dev/null and b/resources/splash-ar.png differ
diff --git a/resources/splash-en.png b/resources/splash-en.png
new file mode 100644
index 0000000..69bc701
Binary files /dev/null and b/resources/splash-en.png differ
diff --git a/resources/table_add.png b/resources/table_add.png
new file mode 100644
index 0000000..39c9d70
Binary files /dev/null and b/resources/table_add.png differ
diff --git a/resources/table_modify.png b/resources/table_modify.png
new file mode 100644
index 0000000..b17ca71
Binary files /dev/null and b/resources/table_modify.png differ
diff --git a/resources/table_print.png b/resources/table_print.png
new file mode 100644
index 0000000..965819c
Binary files /dev/null and b/resources/table_print.png differ
diff --git a/resources/table_remove.png b/resources/table_remove.png
new file mode 100644
index 0000000..b43463e
Binary files /dev/null and b/resources/table_remove.png differ
diff --git a/resources/underline.png b/resources/underline.png
new file mode 100644
index 0000000..31324d9
Binary files /dev/null and b/resources/underline.png differ
diff --git a/resources/zoom-in.png b/resources/zoom-in.png
new file mode 100644
index 0000000..3483e86
Binary files /dev/null and b/resources/zoom-in.png differ
diff --git a/resources/zoom-out.png b/resources/zoom-out.png
new file mode 100644
index 0000000..7ba37f3
Binary files /dev/null and b/resources/zoom-out.png differ
diff --git a/structures/printOption.h b/structures/printOption.h
new file mode 100644
index 0000000..70ec855
--- /dev/null
+++ b/structures/printOption.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef PRINTOPTION_H
+#define PRINTOPTION_H
+
+#include
+#include
+
+class PrintOption : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit PrintOption(QObject *parent = 0);
+
+public slots:
+ QString preamble() const;
+ void setPreamble(const QString &preamble);
+
+ QString commentary() const;
+ void setCommentary(const QString &commentary);
+
+ void setColumnHidden(int column, bool isHidden);
+ bool isColumnHidden(int column) const;
+
+ int hiddenColumnCount();
+
+ void setColumnAggregative(int column, bool isAggregative);
+ bool isColumnAggregative(int column) const;
+
+ void setRowHidden(int row, bool isHidden);
+ bool isRowHidden(int row) const;
+
+ void setAggregationEntryHidden(const QString &entry, bool isHidden);
+ bool isAggregationEntryHidden(const QString &) const;
+
+ void setColumnRemoved(int column, bool isRemoved);
+ bool isColumnRemoved(int column) const;
+
+ void setCurrentAggregativeColumn(int column);
+ int currentAggregativeColumn() const;
+
+ void setMajorColumn(int column);
+ int majorColumn() const;
+
+private:
+ QString m_preamble;
+ QString m_commentary;
+
+ QMap m_hiddenRowMap;
+ QMap m_hiddenColumnMap;
+ QMap m_aggregativeColumnMap;
+ QMap m_removedColumnMap;
+
+ QMap m_hiddenAggregationEntryMap;
+
+ int m_majorColumn;
+ int m_currentAggregativeColumn;
+};
+
+#endif // PRINTOPTION_H
diff --git a/structures/printoption.cpp b/structures/printoption.cpp
new file mode 100644
index 0000000..78ce66b
--- /dev/null
+++ b/structures/printoption.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "printoption.h"
+
+PrintOption::PrintOption(QObject *parent) :
+ QObject(parent),
+ m_majorColumn(1),
+ m_currentAggregativeColumn(-1)
+{}
+
+QString PrintOption::preamble() const
+{
+ return m_preamble;
+}
+
+void PrintOption::setPreamble(const QString &preamble)
+{
+ m_preamble = preamble;
+}
+
+QString PrintOption::commentary() const
+{
+ return m_commentary;
+}
+
+void PrintOption::setCommentary(const QString &commentary)
+{
+ m_commentary = commentary;
+}
+
+void PrintOption::setColumnHidden(int column, bool isHidden)
+{
+ m_hiddenColumnMap.insert(column, isHidden);
+}
+
+bool PrintOption::isColumnHidden(int column) const
+{
+ return m_hiddenColumnMap.value(column, false);
+}
+
+int PrintOption::hiddenColumnCount()
+{
+ return m_hiddenColumnMap.keys(true).size();
+}
+
+void PrintOption::setColumnAggregative(int column, bool isAggregative)
+{
+ m_aggregativeColumnMap.insert(column, isAggregative);
+}
+
+bool PrintOption::isColumnAggregative(int column) const
+{
+ return m_aggregativeColumnMap.value(column, false);
+}
+
+void PrintOption::setRowHidden(int row, bool isHidden)
+{
+ m_hiddenRowMap.insert(row, isHidden);
+}
+
+bool PrintOption::isRowHidden(int row) const
+{
+ return m_hiddenRowMap.value(row, false);
+}
+
+void PrintOption::setAggregationEntryHidden(const QString &entry, bool isHidden)
+{
+ m_hiddenAggregationEntryMap.insert(entry, isHidden);
+}
+
+bool PrintOption::isAggregationEntryHidden(const QString &entry) const
+{
+ return m_hiddenAggregationEntryMap.value(entry, false);
+}
+
+void PrintOption::setColumnRemoved(int column, bool isRemoved)
+{
+ m_removedColumnMap.insert(column, isRemoved);
+}
+
+bool PrintOption::isColumnRemoved(int column) const
+{
+ return m_removedColumnMap.value(column, false);
+}
+
+void PrintOption::setCurrentAggregativeColumn(int column)
+{
+ m_currentAggregativeColumn = column;
+
+ m_hiddenAggregationEntryMap.clear();
+}
+
+int PrintOption::currentAggregativeColumn() const
+{
+ return m_currentAggregativeColumn;
+}
+
+void PrintOption::setMajorColumn(int column)
+{
+ m_majorColumn = column;
+}
+
+int PrintOption::majorColumn() const
+{
+ return m_majorColumn;
+}
diff --git a/structures/richsqlmodel.cpp b/structures/richsqlmodel.cpp
new file mode 100644
index 0000000..cb7c0e6
--- /dev/null
+++ b/structures/richsqlmodel.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "richsqlmodel.h"
+
+#include "abstractrelation.h"
+
+RichSqlModel::RichSqlModel(QObject *parent, QSqlDatabase db) :
+ QSqlTableModel(parent, db)
+{}
+
+void RichSqlModel::setRelation(int column, AbstractRelation *relation)
+{
+ m_relationMap.insert(column, relation);
+}
+
+AbstractRelation *RichSqlModel::relation(int column) const
+{
+ return m_relationMap.value(column, NULL);
+}
+
+QVariant RichSqlModel::data(const QModelIndex &idx, int role) const
+{
+ if (role == Qt::DisplayRole) {
+ if (m_relationMap.find(idx.column()) == m_relationMap.end()) {
+ return QSqlTableModel::data(idx, role);
+ } else {
+ return m_relationMap.value(idx.column())->forwardLookup(QSqlTableModel::data(idx).toLongLong());
+ }
+ } else {
+ return QSqlTableModel::data(idx, role);
+ }
+ return QVariant();
+}
diff --git a/structures/richsqlmodel.h b/structures/richsqlmodel.h
new file mode 100644
index 0000000..31da46d
--- /dev/null
+++ b/structures/richsqlmodel.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef RICHSQLMODEL_H
+#define RICHSQLMODEL_H
+
+#include
+
+class AbstractRelation;
+
+class RichSqlModel : public QSqlTableModel
+{
+ Q_OBJECT
+
+public:
+ explicit RichSqlModel(QObject *parent = 0, QSqlDatabase db = QSqlDatabase());
+
+ void setRelation(int column, AbstractRelation *);
+
+ AbstractRelation *relation(int column) const;
+
+ QVariant data(const QModelIndex &idx, int role) const;
+
+private:
+ QMap m_relationMap;
+ QList m_hiddenColumnList;
+ int m_columnCollapsed;
+};
+
+#endif // RICHSQLMODEL_H
diff --git a/translations/ar.ts b/translations/ar.ts
new file mode 100644
index 0000000..4258a60
--- /dev/null
+++ b/translations/ar.ts
@@ -0,0 +1,825 @@
+
+
+
+
+ CompetitorWidget
+
+
+ Competition
+ المسابقة
+
+
+
+ Competitor
+ المتسابق
+
+
+
+ Please select a competition first.
+ أولاً اختر منافسة من فضلك
+
+
+
+ EmployeeWidget
+
+
+ Job
+ الوظيفة
+
+
+
+ Employee
+ الموظف
+
+
+
+ Please select a job first.
+ أولاً اختر وظيفة من فضلك
+
+
+
+ MainWidget
+
+
+
+ Furqan
+ فرقان
+
+
+
+ &Add
+ &إضافة
+
+
+
+ &Modify
+ &تعديل
+
+
+
+ &Remove
+ &حذف
+
+
+
+ &Print
+ &طباعة
+
+
+
+ Classes
+ الصفوف
+
+
+
+ Courses
+ المواد
+
+
+
+ Students
+ الطلاب
+
+
+
+ Teachers
+ المعلمون
+
+
+
+ Teaching
+ التعليم
+
+
+
+ Results of Courses
+ نتائج المواد
+
+
+
+ Studies of Quran
+ دراسات القرآن
+
+
+
+ Competitions
+ المسابقات
+
+
+
+ Competitors
+ المتسابقون
+
+
+
+ Jobs
+ الوظائف
+
+
+
+ Employees
+ الموظفون
+
+
+
+ Setting
+ الضبط
+
+
+
+ MapHandler
+
+
+
+
+
+
+ None
+ بلا
+
+
+
+ Male
+ ذكر
+
+
+
+ Female
+ أنثى
+
+
+
+ Basic
+ مبتدئ
+
+
+
+ Intermediate
+ متوسط
+
+
+
+ Advanced
+ متقدم
+
+
+
+ First
+ الأول
+
+
+
+ Second
+ الثاني
+
+
+
+ Daily
+ يومية
+
+
+
+ Weekly
+ أسبوعية
+
+
+
+ Quarterly
+ فصلية
+
+
+
+ Reading
+ قراءة
+
+
+
+ Memorizing
+ حفظ
+
+
+
+ Reviewing
+ مراجعة
+
+
+
+ ModelHandler
+
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ معرف
+
+
+
+
+
+
+ Name
+ الاسم
+
+
+
+
+ Level
+ المستوى
+
+
+
+ Semester
+ الفصل
+
+
+
+
+
+ Full Name
+ الاسم الكامل
+
+
+
+
+
+ Father Name
+ اسم الأب
+
+
+
+
+
+ Gender
+ الجنس
+
+
+
+
+
+ Birth Place
+ مكان الولادة
+
+
+
+
+
+ Birth Date
+ تاريخ الولادة
+
+
+
+
+
+ Residency
+ مكان الإقامة
+
+
+
+
+
+ Nationality
+ الجنسية
+
+
+
+
+
+ National Number
+ الرقم الوطني
+
+
+
+
+
+ Mobile
+ موبايل
+
+
+
+ Father Job
+ عمل الأب
+
+
+
+
+ Class
+ الصف
+
+
+
+ Qualification
+ المؤهلات
+
+
+
+ Experience
+ الخبرة
+
+
+
+ Teacher
+ المعلم
+
+
+
+
+ Course
+ المادة
+
+
+
+
+
+ Student
+ الطالب
+
+
+
+ Result
+ النتيجة
+
+
+
+ Recital Type
+ التلاوة
+
+
+
+ From Page
+ من صفحة
+
+
+
+ To Page
+ إلى صفحة
+
+
+
+
+ Date
+ التاريخ
+
+
+
+ Type
+ النوع
+
+
+
+ Part(s)
+ الأجزاء
+
+
+
+ Competition
+ المسابقة
+
+
+
+ Rank
+ الترتيب
+
+
+
+ Job
+ الوظيفة
+
+
+
+ Other Job
+ عمل آخر
+
+
+
+ Header
+ رأسية
+
+
+
+ Cell
+ خلية
+
+
+
+ PrintDialog
+
+
+
+ Print
+ طباعة
+
+
+
+ Close
+ إغلاق
+
+
+
+ Shown Columns
+ الأعمدة المرئية
+
+
+
+ Aggregative Columns
+ تجميع وفق عمود
+
+
+
+ Aggragative Column Entries
+ مفردات عمود التجميع المرئية
+
+
+
+ Shown Rows
+ الأسطر المرئية
+
+
+
+ None
+ بلا
+
+
+
+ Preamble
+ التوطئة
+
+
+
+ Table
+ الجدول
+
+
+
+ Commentary
+ التعقيب
+
+
+
+ QObject
+
+
+ Program couldn't open the current database, please select another one
+ تعثر فتح قاعدة البيانات الحالية ، يرجى اختيار أخرى أو إنشاء جديدة
+
+
+
+ Database is damaged, Program cannot proceed
+ قاعدة البيانات معطوبة ، لا يمكن إتمام العملية
+
+
+
+ QuranWidget
+
+
+ Student
+ الطالب
+
+
+
+ Recital
+ المتابعة
+
+
+
+ Please select a student first.
+ أولاً اختر طالباً من فضلك
+
+
+
+ RelationalDelegate
+
+
+ Database Error
+ خطأ متعلق بقاعدة البيانات
+
+
+
+ ResultWidget
+
+
+ Course
+ المادة
+
+
+
+ Result
+ النتيجة
+
+
+
+ SettingWidget
+
+
+ General
+ عام
+
+
+
+
+ Printer
+ الطابعة
+
+
+
+ Report
+ التقرير
+
+
+
+ Database
+ قاعدة البيانات
+
+
+
+ Path:
+ المسار:
+
+
+
+
+
+ ...
+ ...
+
+
+
+ Backup
+ نسخ
+
+
+
+ Change
+ ربط
+
+
+
+ Create
+ إنشاء
+
+
+
+ Language
+ اللغة
+
+
+
+ Paper Size
+ حجم الورق
+
+
+
+ A4
+ A4
+
+
+
+ A5
+ A5
+
+
+
+ Color Mode
+ نمط اللون
+
+
+
+ Grayscale
+ تدرج الرمادي
+
+
+
+ Color
+ ملون
+
+
+
+ Orientation
+ التوجيه
+
+
+
+ Portrait
+ طولي
+
+
+
+ Landscape
+ عرضي
+
+
+
+ Margins
+ الهامش
+
+
+
+ Top
+ أعلى
+
+
+
+
+
+
+
+
+ mm
+ مم
+
+
+
+ Bottom
+ أسفل
+
+
+
+ Right
+ يمين
+
+
+
+ Left
+ يسار
+
+
+
+ Header
+ رأسية
+
+
+
+ None
+ بلا
+
+
+
+ Image
+ صورة
+
+
+
+ Width
+ عرض
+
+
+
+ Height
+ ارتفاع
+
+
+
+ Arabic
+ عربي
+
+
+
+ English
+ إنكليزي
+
+
+
+ Select a database
+ إختر قاعدة بيانات
+
+
+
+ Program cannot use the selected database
+ لا يمكن استخدام قاعدة البيانات المختارة
+
+
+
+ Database Changed
+ تم تغيير قاعدة البيانات
+
+
+
+ A database with the same name exists !
+ يوجد قاعدة بيانات بنفس الاسم !
+
+
+
+ Select where to save the back up
+ إختر مكاناً لحفظ النسخة الإحتياطية
+
+
+
+
+ Process cannot complete, an error occured
+ Process couldn't complete, an error occured
+ حدث خطأ ، لا يمكن إتمام العملية
+
+
+
+ Backup Created
+ تم أخذ نسخة إحتياطية
+
+
+
+ Select where to save the new database
+ إختر مكاناً لحفظ قاعدة البيانات الجديدة
+
+
+
+ Database Created
+ تم إنشاء قاعدة البيانات
+
+
+
+ StudentWidget
+
+
+ Class
+ الصف
+
+
+
+ Student
+ الطالب
+
+
+
+ Please select a class first.
+ أولاً اختر صفاً من فضلك
+
+
+
+ TeacherWidget
+
+
+ Teacher
+ المعلم
+
+
+
+ TeachingWidget
+
+
+ Teacher
+ المعلم
+
+
+
+ Teaching
+ التعليم
+
+
+
+ Please select a teacher first.
+ أولاً اختر معلماً من فضلك
+
+
+
+ TextEditor
+
+
+ Bold
+ غامق
+
+
+
+ Ctrl+B
+
+
+
+
+ Italic
+ مائل
+
+
+
+ Ctrl+I
+
+
+
+
+ Underline
+ خط تحتي
+
+
+
+ Ctrl+U
+
+
+
+
+ Color
+ لون
+
+
+
+ UniqueDelegate
+
+
+ Database Error
+ خطأ متعلق بقاعدة البيانات
+
+
+
diff --git a/translations/en.ts b/translations/en.ts
new file mode 100644
index 0000000..1e19ecb
--- /dev/null
+++ b/translations/en.ts
@@ -0,0 +1,825 @@
+
+
+
+
+ CompetitorWidget
+
+
+ Competition
+
+
+
+
+ Competitor
+
+
+
+
+ Please select a competition first.
+
+
+
+
+ EmployeeWidget
+
+
+ Job
+
+
+
+
+ Employee
+
+
+
+
+ Please select a job first.
+
+
+
+
+ MainWidget
+
+
+
+ Furqan
+
+
+
+
+ &Add
+
+
+
+
+ &Modify
+
+
+
+
+ &Remove
+
+
+
+
+ &Print
+
+
+
+
+ Classes
+
+
+
+
+ Courses
+
+
+
+
+ Students
+
+
+
+
+ Teachers
+
+
+
+
+ Teaching
+
+
+
+
+ Results of Courses
+
+
+
+
+ Studies of Quran
+
+
+
+
+ Competitions
+
+
+
+
+ Competitors
+
+
+
+
+ Jobs
+
+
+
+
+ Employees
+
+
+
+
+ Setting
+
+
+
+
+ MapHandler
+
+
+
+
+
+
+ None
+
+
+
+
+ Male
+
+
+
+
+ Female
+
+
+
+
+ Basic
+
+
+
+
+ Intermediate
+
+
+
+
+ Advanced
+
+
+
+
+ First
+
+
+
+
+ Second
+
+
+
+
+ Daily
+
+
+
+
+ Weekly
+
+
+
+
+ Quarterly
+
+
+
+
+ Reading
+
+
+
+
+ Memorizing
+
+
+
+
+ Reviewing
+
+
+
+
+ ModelHandler
+
+
+
+
+
+
+
+
+
+
+
+
+ ID
+
+
+
+
+
+
+
+ Name
+
+
+
+
+
+ Level
+
+
+
+
+ Semester
+
+
+
+
+
+
+ Full Name
+
+
+
+
+
+
+ Father Name
+
+
+
+
+
+
+ Gender
+
+
+
+
+
+
+ Birth Place
+
+
+
+
+
+
+ Birth Date
+
+
+
+
+
+
+ Residency
+
+
+
+
+
+
+ Nationality
+
+
+
+
+
+
+ National Number
+
+
+
+
+
+
+ Mobile
+
+
+
+
+ Father Job
+
+
+
+
+
+ Class
+
+
+
+
+ Qualification
+
+
+
+
+ Experience
+
+
+
+
+ Teacher
+
+
+
+
+
+ Course
+
+
+
+
+
+
+ Student
+
+
+
+
+ Result
+
+
+
+
+ Recital Type
+
+
+
+
+ From Page
+
+
+
+
+ To Page
+
+
+
+
+
+ Date
+
+
+
+
+ Type
+
+
+
+
+ Part(s)
+
+
+
+
+ Competition
+
+
+
+
+ Rank
+
+
+
+
+ Job
+
+
+
+
+ Other Job
+
+
+
+
+ Header
+
+
+
+
+ Cell
+
+
+
+
+ PrintDialog
+
+
+
+ Print
+
+
+
+
+ Close
+
+
+
+
+ Shown Columns
+
+
+
+
+ Aggregative Columns
+
+
+
+
+ Aggragative Column Entries
+
+
+
+
+ Shown Rows
+
+
+
+
+ None
+
+
+
+
+ Preamble
+
+
+
+
+ Table
+
+
+
+
+ Commentary
+
+
+
+
+ QObject
+
+
+ Program couldn't open the current database, please select another one
+
+
+
+
+ Database is damaged, Program cannot proceed
+
+
+
+
+ QuranWidget
+
+
+ Student
+
+
+
+
+ Recital
+
+
+
+
+ Please select a student first.
+
+
+
+
+ RelationalDelegate
+
+
+ Database Error
+
+
+
+
+ ResultWidget
+
+
+ Course
+
+
+
+
+ Result
+
+
+
+
+ SettingWidget
+
+
+
+
+ ...
+
+
+
+
+ General
+
+
+
+
+
+ Printer
+
+
+
+
+ Report
+
+
+
+
+ Database
+
+
+
+
+ Path:
+
+
+
+
+ Backup
+
+
+
+
+ Change
+
+
+
+
+ Create
+
+
+
+
+ Language
+
+
+
+
+ Paper Size
+
+
+
+
+ A4
+
+
+
+
+ A5
+
+
+
+
+ Color Mode
+
+
+
+
+ Grayscale
+
+
+
+
+ Color
+
+
+
+
+ Orientation
+
+
+
+
+ Portrait
+
+
+
+
+ Landscape
+
+
+
+
+ Margins
+
+
+
+
+ Top
+
+
+
+
+
+
+
+
+
+ mm
+
+
+
+
+ Bottom
+
+
+
+
+ Right
+
+
+
+
+ Left
+
+
+
+
+ Header
+
+
+
+
+ None
+
+
+
+
+ Image
+
+
+
+
+ Width
+
+
+
+
+ Height
+
+
+
+
+ Arabic
+
+
+
+
+ English
+
+
+
+
+ Select a database
+
+
+
+
+ Program cannot use the selected database
+
+
+
+
+ Database Changed
+
+
+
+
+ A database with the same name exists !
+
+
+
+
+ Select where to save the back up
+
+
+
+
+
+ Process cannot complete, an error occured
+ Process couldn't complete, an error occured
+
+
+
+
+ Backup Created
+
+
+
+
+ Select where to save the new database
+
+
+
+
+ Database Created
+
+
+
+
+ StudentWidget
+
+
+ Class
+
+
+
+
+ Student
+
+
+
+
+ Please select a class first.
+
+
+
+
+ TeacherWidget
+
+
+ Teacher
+
+
+
+
+ TeachingWidget
+
+
+ Teacher
+
+
+
+
+ Teaching
+
+
+
+
+ Please select a teacher first.
+
+
+
+
+ TextEditor
+
+
+ Bold
+
+
+
+
+ Ctrl+B
+
+
+
+
+ Italic
+
+
+
+
+ Ctrl+I
+
+
+
+
+ Underline
+
+
+
+
+ Ctrl+U
+
+
+
+
+ Color
+
+
+
+
+ UniqueDelegate
+
+
+ Database Error
+
+
+
+
diff --git a/utility/enumeration.h b/utility/enumeration.h
new file mode 100644
index 0000000..e3dda93
--- /dev/null
+++ b/utility/enumeration.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef ENUMERATION_H
+#define ENUMERATION_H
+
+#include "generalenumeration.h"
+#include "sqlenumeration.h"
+#include "mapenumeration.h"
+
+enum HeaderType {
+ None,
+ Image
+};
+
+enum Language {
+ Arabic,
+ English
+};
+
+#endif // ENUMERATION_H
diff --git a/utility/generalenumeration.h b/utility/generalenumeration.h
new file mode 100644
index 0000000..f1ffb36
--- /dev/null
+++ b/utility/generalenumeration.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef GENERALENUMERATION_H
+#define GENERALENUMERATION_H
+
+namespace NS_HeaderType {
+enum HeaderType {
+ None,
+ Image
+};
+}
+
+namespace NS_Language {
+enum Language {
+ Arabic,
+ English
+};
+}
+
+#endif // GENERALENUMERATION_H
diff --git a/utility/mapenumeration.h b/utility/mapenumeration.h
new file mode 100644
index 0000000..dbd20b2
--- /dev/null
+++ b/utility/mapenumeration.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef MAPENUMERATION_H
+#define MAPENUMERATION_H
+
+namespace NS_MAP {
+enum MAP{
+ GENDER,
+ LEVEL,
+ SEMESTER,
+ COMPETITION,
+ RECITAL
+};
+}
+
+namespace NS_GENDER {
+enum {
+ NONE,
+ MALE,
+ FEMALE
+};
+}
+
+namespace NS_LEVEL {
+enum {
+ NONE,
+ BASIC,
+ INTERMEDIATE,
+ ADVANCED
+};
+}
+
+namespace NS_SEMESTER {
+enum {
+ NONE,
+ FIRST,
+ SECOND
+};
+}
+
+namespace NS_COMPETITION_TYPE {
+enum {
+ NONE,
+ DAILY,
+ WEEKLY,
+ QUARTERLY
+};
+}
+
+namespace NS_RECITAL {
+enum {
+ NONE,
+ READING,
+ MEMORIZING,
+ REVIEWING
+};
+}
+
+#endif // MAPENUMERATION_H
diff --git a/utility/resourcemanager.cpp b/utility/resourcemanager.cpp
new file mode 100644
index 0000000..f81f30c
--- /dev/null
+++ b/utility/resourcemanager.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "resourcemanager.h"
+
+#include
+#include
+#include
+
+TranslatorHandler *RscMgr::translatorHandler()
+{
+ return TranslatorHandler::singleton();
+}
+
+SettingHandler *RscMgr::settingHandler()
+{
+ return SettingHandler::singleton();
+}
+
+DatabaseHandler *RscMgr::databaseHandler()
+{
+ return DatabaseHandler::singleton();
+}
+
+MapHandler *RscMgr::mapHandler()
+{
+ return MapHandler::singleton();
+}
+
+ModelHandler *RscMgr::modelHandler()
+{
+ return ModelHandler::singleton();
+}
+
+PrinterHandler *RscMgr::printHandler()
+{
+ return PrinterHandler::singleton();
+}
+
+Qt::LayoutDirection RscMgr::dir()
+{
+ switch (RscMgr::settingHandler()->interfaceLanguage()) {
+ case NS_Language::Arabic:
+ return Qt::RightToLeft;
+ case NS_Language::English:
+ return Qt::LeftToRight;
+ default:
+ break;
+ }
+
+ return Qt::LeftToRight;
+}
+
+void RscMgr::issueMessage(const QString &text, bool ok)
+{
+ QMessageBox msg;
+ msg.setLayoutDirection(RscMgr::dir());
+ msg.setText(QString("%1").arg(text));
+ msg.setWindowFlags(Qt::Window | Qt::CustomizeWindowHint);
+ msg.setIconPixmap(ok ? QPixmap(":/emotion-happy") : QPixmap(":/emotion-sad"));
+ msg.setStyleSheet("QMessageBox {"
+ " background-color: lightgray;"
+ "}"
+ "QPushButton {"
+ " background: transparent;"
+ " padding: 5px;"
+ "}"
+ "QPushButton:hover {"
+ " color: white;"
+ " border: 1px solid darkgray;"
+ "}"
+ );
+
+ QPushButton *backButton = new QPushButton("OK");
+ backButton->setFocusPolicy(Qt::NoFocus);
+ backButton->setIconSize(QSize(32, 32));
+ backButton->setToolTip("Enter");
+
+ msg.addButton(backButton, QMessageBox::AcceptRole);
+ msg.exec();
+}
+
+
+QSplashScreen *RscMgr::createSplashScreen()
+{
+ QSplashScreen *splashScreen = new QSplashScreen;
+ splashScreen->setAttribute(Qt::WA_DeleteOnClose);
+ splashScreen->setWindowFlags(Qt::Window | Qt::CustomizeWindowHint);
+ switch (RscMgr::settingHandler()->interfaceLanguage()) {
+ case NS_Language::Arabic:
+ splashScreen->setPixmap(QPixmap(":/splash-ar"));
+ break;
+ case NS_Language::English:
+ splashScreen->setPixmap(QPixmap(":/splash-en"));
+ break;
+ default:
+ break;
+ }
+ splashScreen->setWindowModality(Qt::ApplicationModal);
+ return splashScreen;
+}
diff --git a/utility/resourcemanager.h b/utility/resourcemanager.h
new file mode 100644
index 0000000..3ed6cac
--- /dev/null
+++ b/utility/resourcemanager.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef RESOURCEMANAGER_H
+#define RESOURCEMANAGER_H
+
+#include "settinghandler.h"
+#include "translatorhandler.h"
+#include "databasehandler.h"
+#include "maphandler.h"
+#include "modelhandler.h"
+#include "printerhandler.h"
+
+class QSqlDatabase;
+class QSplashScreen;
+
+namespace RscMgr {
+
+SettingHandler *settingHandler();
+
+TranslatorHandler *translatorHandler();
+
+DatabaseHandler *databaseHandler();
+
+MapHandler *mapHandler();
+
+ModelHandler *modelHandler();
+
+PrinterHandler *printHandler();
+
+Qt::LayoutDirection dir();
+
+void issueMessage(const QString &text, bool ok);
+
+QSplashScreen *createSplashScreen();
+}
+
+#endif // RESOURCEMANAGER_H
diff --git a/utility/settingenumeration.h b/utility/settingenumeration.h
new file mode 100644
index 0000000..72bed4d
--- /dev/null
+++ b/utility/settingenumeration.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef SETTINGENUMERATION_H
+#define SETTINGENUMERATION_H
+
+namespace NS_Setting {
+enum SettingEntry {
+ InterfaceLanguage,
+
+ DatabasePath,
+
+ PrinterName,
+ PrinterPaperSize,
+ PrinterColorMode,
+ PrinterOrientation,
+ PrinterTopMargin,
+ PrinterBottomMargin,
+ PrinterRightMargin,
+ PrinterLeftMargin,
+
+ HeaderType,
+ HeaderImagePath,
+ HeaderWidth,
+ HeaderHeight,
+ HeaderAlignment,
+
+ PreambleFontFamily,
+ PreambleFontSize,
+ PreambleFontColor,
+
+ CommentaryFontFamily,
+ CommentaryFontSize,
+ CommentaryFontColor,
+
+ TableFontFamily,
+ TableFontSize,
+ TableFontColor
+};
+}
+
+#endif // SETTINGENUMERATION_H
diff --git a/utility/sqlenumeration.h b/utility/sqlenumeration.h
new file mode 100644
index 0000000..2c7d2d1
--- /dev/null
+++ b/utility/sqlenumeration.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef SQLENUMERATION_H
+#define SQLENUMERATION_H
+
+namespace NS_TABLE {
+enum TABLE {
+ CLASS,
+ COURSE,
+ STUDENT,
+ TEACHER,
+ TEACHING,
+ RESULT,
+ QURAN,
+ COMPETITION,
+ COMPETITOR,
+ JOB,
+ EMPLOYEE
+};
+}
+
+namespace NS_CLASS {
+enum {
+ ID,
+ NAME,
+ LEVEL
+};
+}
+
+namespace NS_COURSE {
+enum {
+ ID,
+ NAME,
+ SEMESTER
+};
+}
+
+namespace NS_STUDENT {
+enum {
+ ID,
+ FULL_NAME,
+ FATHER_NAME,
+ GENDER,
+ BIRTH_PLACE,
+ BIRTH_DATE,
+ RESIDENCY,
+ NATIONALITY,
+ NATIONAL_ID,
+ MOBILE,
+ FATHER_JOB,
+ LEVEL,
+ CLASS,
+};
+}
+
+namespace NS_QURAN {
+enum {
+ ID,
+ STUDENT,
+ RECITAL_TYPE,
+ FROM_PAGE,
+ TO_PAGE,
+ DATE
+};
+}
+
+namespace NS_TEACHER {
+enum {
+ ID,
+ FULL_NAME,
+ FATHER_NAME,
+ GENDER,
+ BIRTH_PLACE,
+ BIRTH_DATE,
+ RESIDENCY,
+ NATIONALITY,
+ NATIONAL_ID,
+ MOBILE,
+ QUALIFICATION,
+ EXPERIENCE
+};
+}
+
+namespace NS_JOB {
+enum {
+ ID,
+ NAME
+};
+}
+
+namespace NS_EMPLOYEE {
+enum {
+ ID,
+ FULL_NAME,
+ FATHER_NAME,
+ GENDER,
+ BIRTH_PLACE,
+ BIRTH_DATE,
+ RESIDENCY,
+ NATIONALITY,
+ NATIONAL_ID,
+ MOBILE,
+ JOB,
+ OTHER_JOB
+};
+}
+
+namespace NS_TEACHING {
+enum {
+ ID,
+ TEACHER,
+ CLASS,
+ COURSE
+};
+}
+
+namespace NS_RESULT {
+enum {
+ ID,
+ COURSE,
+ STUDENT,
+ RESULT
+};
+}
+
+namespace NS_COMPETITION {
+enum {
+ ID,
+ NAME,
+ TYPE,
+ PARTS,
+ DATE
+};
+}
+
+namespace NS_COMPETITOR {
+enum {
+ ID,
+ COMPETITION,
+ STUDENT,
+ RANK
+};
+}
+
+#endif // SQLENUMERATION_H
diff --git a/widgets/classwidget.cpp b/widgets/classwidget.cpp
new file mode 100644
index 0000000..eddf04c
--- /dev/null
+++ b/widgets/classwidget.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "classwidget.h"
+#include "ui_classwidget.h"
+
+#include "resourcemanager.h"
+#include "uniquedelegate.h"
+#include "mapdelegate.h"
+#include "printdialog.h"
+#include "printoption.h"
+
+#include
+
+ClassWidget::ClassWidget(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::ClassWidget)
+{
+ ui->setupUi(this);
+
+ ui->classView->setModel(RscMgr::modelHandler()->model(NS_TABLE::CLASS));
+ ui->classView->hideColumn(NS_CLASS::ID);
+ ui->classView->setItemDelegateForColumn(NS_CLASS::NAME, new UniqueDelegate(ui->classView));
+ ui->classView->setItemDelegateForColumn(NS_CLASS::LEVEL, new MapDelegate(ui->classView));
+ ui->classView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+}
+
+ClassWidget::~ClassWidget()
+{
+ delete ui;
+}
+
+void ClassWidget::add()
+{
+ QMap map;
+ map.insert(NS_CLASS::LEVEL, NS_LEVEL::NONE);
+
+ RscMgr::modelHandler()->insertRow(NS_TABLE::CLASS, map);
+
+ const QModelIndex &idx = ui->classView->model()->index(0, NS_CLASS::NAME);
+
+ ui->classView->setCurrentIndex(idx);
+ ui->classView->edit(idx);
+}
+
+void ClassWidget::modify()
+{
+ if (!ui->classView->currentIndex().isValid())
+ return;
+
+ ui->classView->edit(ui->classView->currentIndex());
+}
+
+void ClassWidget::remove()
+{
+ if (!ui->classView->currentIndex().isValid())
+ return;
+
+ RscMgr::modelHandler()->removeRow(NS_TABLE::CLASS, ui->classView->currentIndex().row());
+
+ ui->classView->setFocus();
+ ui->classView->setCurrentIndex(ui->classView->model()->index(0, NS_CLASS::NAME));
+}
+
+void ClassWidget::print()
+{
+ PrintOption opt;
+
+ opt.setColumnRemoved(NS_CLASS::ID, true);
+ opt.setColumnHidden(NS_CLASS::ID, true);
+ opt.setMajorColumn(NS_CLASS::NAME);
+ opt.setColumnAggregative(NS_CLASS::LEVEL, true);
+ opt.setCurrentAggregativeColumn(-1);
+
+ PrintDialog dlg(ui->classView->model(), &opt);
+
+ dlg.exec();
+}
diff --git a/widgets/classwidget.h b/widgets/classwidget.h
new file mode 100644
index 0000000..bbe74ef
--- /dev/null
+++ b/widgets/classwidget.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef CLASSWIDGET_H
+#define CLASSWIDGET_H
+
+#include
+
+namespace Ui {
+class ClassWidget;
+}
+
+class ClassWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ClassWidget(QWidget *parent = 0);
+
+ ~ClassWidget();
+
+ void add();
+
+ void modify();
+
+ void remove();
+
+ void print();
+
+private:
+ Ui::ClassWidget *ui;
+};
+
+#endif // CLASSWIDGET_H
diff --git a/widgets/competitionwidget.cpp b/widgets/competitionwidget.cpp
new file mode 100644
index 0000000..a424641
--- /dev/null
+++ b/widgets/competitionwidget.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "competitionwidget.h"
+#include "ui_competitionwidget.h"
+
+#include "resourcemanager.h"
+#include "uniquedelegate.h"
+#include "mapdelegate.h"
+#include "datedelegate.h"
+#include "printdialog.h"
+#include "printoption.h"
+
+CompetitionWidget::CompetitionWidget(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::CompetitionWidget)
+{
+ ui->setupUi(this);
+
+ ui->competitionView->setModel(RscMgr::modelHandler()->model(NS_TABLE::COMPETITION));
+ ui->competitionView->hideColumn(NS_COMPETITION::ID);
+ ui->competitionView->setItemDelegateForColumn(NS_COMPETITION::NAME, new UniqueDelegate(ui->competitionView));
+ ui->competitionView->setItemDelegateForColumn(NS_COMPETITION::TYPE, new MapDelegate(ui->competitionView));
+ ui->competitionView->setItemDelegateForColumn(NS_COMPETITION::DATE, new DateDelegate(ui->competitionView));
+ ui->competitionView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
+ ui->competitionView->horizontalHeader()->setSectionResizeMode(NS_COMPETITION::NAME, QHeaderView::Stretch);
+}
+
+CompetitionWidget::~CompetitionWidget()
+{
+ delete ui;
+}
+
+void CompetitionWidget::add()
+{
+ RscMgr::modelHandler()->insertRow(NS_TABLE::COMPETITION);
+
+ const QModelIndex &idx = ui->competitionView->model()->index(0, NS_COMPETITION::NAME);
+
+ ui->competitionView->setCurrentIndex(idx);
+ ui->competitionView->edit(idx);
+}
+
+void CompetitionWidget::modify()
+{
+ if (!ui->competitionView->currentIndex().isValid())
+ return;
+
+ ui->competitionView->edit(ui->competitionView->currentIndex());
+}
+
+void CompetitionWidget::remove()
+{
+ if (!ui->competitionView->currentIndex().isValid())
+ return;
+
+ RscMgr::modelHandler()->removeRow(NS_TABLE::COMPETITION, ui->competitionView->currentIndex().row());
+
+ ui->competitionView->setFocus();
+ ui->competitionView->setCurrentIndex(ui->competitionView->model()->index(0, NS_COMPETITION::NAME));
+}
+
+void CompetitionWidget::print()
+{
+ PrintOption opt;
+
+ opt.setColumnRemoved(NS_COMPETITION::ID, true);
+ opt.setColumnHidden(NS_COMPETITION::ID, true);
+ opt.setMajorColumn(NS_COMPETITION::NAME);
+ opt.setColumnAggregative(NS_COMPETITION::TYPE, true);
+ opt.setCurrentAggregativeColumn(-1);
+
+ PrintDialog dlg(ui->competitionView->model(), &opt);
+ dlg.exec();
+}
diff --git a/widgets/competitionwidget.h b/widgets/competitionwidget.h
new file mode 100644
index 0000000..d88c184
--- /dev/null
+++ b/widgets/competitionwidget.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef COMPETITIONWIDGET_H
+#define COMPETITIONWIDGET_H
+
+#include
+
+namespace Ui {
+class CompetitionWidget;
+}
+
+class CompetitionWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit CompetitionWidget(QWidget *parent = 0);
+
+ ~CompetitionWidget();
+
+ void add();
+
+ void modify();
+
+ void remove();
+
+ void print();
+
+private:
+ Ui::CompetitionWidget *ui;
+};
+
+#endif // COMPETITIONWIDGET_H
diff --git a/widgets/competitorwidget.cpp b/widgets/competitorwidget.cpp
new file mode 100644
index 0000000..e3bb060
--- /dev/null
+++ b/widgets/competitorwidget.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "competitorwidget.h"
+#include "ui_competitorwidget.h"
+
+#include "resourcemanager.h"
+#include "sqldelegate.h"
+#include "numericdelegate.h"
+#include "printdialog.h"
+#include "printoption.h"
+
+#include
+#include
+
+CompetitorWidget::CompetitorWidget(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::CompetitorWidget)
+{
+ ui->setupUi(this);
+
+ m_competitorProxyModel = new QSortFilterProxyModel(this);
+ m_competitorProxyModel->setSourceModel(RscMgr::modelHandler()->model(NS_TABLE::COMPETITOR));
+ m_competitorProxyModel->setFilterKeyColumn(NS_COMPETITOR::COMPETITION);
+
+ ui->competitorView->setModel(m_competitorProxyModel);
+ ui->competitorView->hideColumn(NS_COMPETITOR::ID);
+ ui->competitorView->hideColumn(NS_COMPETITOR::COMPETITION);
+ ui->competitorView->setItemDelegateForColumn(NS_COMPETITOR::STUDENT, new SqlDelegate(true, ui->competitorView));
+ ui->competitorView->setItemDelegateForColumn(NS_COMPETITOR::RANK, new NumericDelegate(new QIntValidator(0, INT_MAX, this), this));
+ ui->competitorView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
+ ui->competitorView->horizontalHeader()->setSectionResizeMode(NS_COMPETITOR::STUDENT, QHeaderView::Stretch);
+
+ ui->competitionView->setModel(RscMgr::modelHandler()->model(NS_TABLE::COMPETITION));
+ ui->competitionView->setModelColumn(NS_COMPETITION::NAME);
+ ui->competitionView->setCurrentIndex(ui->competitionView->model()->index(0, NS_COMPETITION::NAME));
+ ui->competitionView->setFixedWidth(ui->competitionView->minimumSizeHint().width()
+ + ui->competitionView->verticalScrollBar()->sizeHint().width()
+ + 7);
+
+ connect(ui->competitionView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(adjustToCompetition()));
+ connect(ui->competitionView->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(refresh()));
+
+ adjustToCompetition();
+}
+
+CompetitorWidget::~CompetitorWidget()
+{
+ delete ui;
+}
+
+void CompetitorWidget::adjustToCompetition()
+{
+ m_competitorProxyModel->setFilterRegExp(QString("^%1$").arg(ui->competitionView->currentIndex().data().toString()));
+}
+
+void CompetitorWidget::refresh()
+{
+ RscMgr::modelHandler()->model(NS_TABLE::COMPETITOR)->select();
+ adjustToCompetition();
+}
+
+void CompetitorWidget::add()
+{
+ if (!ui->competitionView->currentIndex().isValid()) {
+ RscMgr::issueMessage(tr("Please select a competition first."), false);
+ return;
+ }
+
+ QMap map;
+ map.insert(NS_COMPETITOR::COMPETITION,
+ ui->competitionView->currentIndex()
+ .sibling(ui->competitionView->currentIndex().row(), NS_COMPETITION::ID).data());
+
+ RscMgr::modelHandler()->insertRow(NS_TABLE::COMPETITOR, map);
+
+ const QModelIndex &idx = ui->competitorView->model()->index(0, NS_COMPETITOR::STUDENT);
+
+ ui->competitorView->setCurrentIndex(idx);
+ ui->competitorView->edit(idx);
+}
+
+void CompetitorWidget::modify()
+{
+ if (!ui->competitorView->currentIndex().isValid())
+ return;
+
+ ui->competitorView->edit(ui->competitorView->currentIndex());
+}
+
+void CompetitorWidget::remove()
+{
+ if (!ui->competitorView->currentIndex().isValid())
+ return;
+
+ RscMgr::modelHandler()->removeRow(NS_TABLE::COMPETITOR, ui->competitorView->currentIndex().row());
+
+ ui->competitorView->setFocus();
+ ui->competitorView->setCurrentIndex(ui->competitorView->model()->index(0, NS_COMPETITOR::STUDENT));
+}
+
+void CompetitorWidget::print()
+{
+ PrintOption opt;
+
+ opt.setColumnRemoved(NS_COMPETITOR::ID, true);
+ opt.setColumnHidden(NS_COMPETITOR::ID, true);
+ opt.setColumnHidden(NS_COMPETITOR::COMPETITION, true);
+ opt.setMajorColumn(NS_COMPETITOR::STUDENT);
+ opt.setColumnAggregative(NS_COMPETITOR::COMPETITION, true);
+ opt.setColumnAggregative(NS_COMPETITOR::RANK, true);
+ opt.setCurrentAggregativeColumn(NS_COMPETITOR::COMPETITION);
+
+ PrintDialog dlg(m_competitorProxyModel->sourceModel(), &opt);
+
+ dlg.exec();
+}
diff --git a/widgets/competitorwidget.h b/widgets/competitorwidget.h
new file mode 100644
index 0000000..56529fa
--- /dev/null
+++ b/widgets/competitorwidget.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef COMPETITORWIDGET_H
+#define COMPETITORWIDGET_H
+
+#include
+
+class QSortFilterProxyModel;
+
+namespace Ui {
+class CompetitorWidget;
+}
+
+class CompetitorWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit CompetitorWidget(QWidget *parent = 0);
+
+ ~CompetitorWidget();
+
+ void add();
+
+ void modify();
+
+ void remove();
+
+ void print();
+
+private slots:
+ void adjustToCompetition();
+
+ void refresh();
+
+private:
+ Ui::CompetitorWidget *ui;
+
+ QSortFilterProxyModel *m_competitorProxyModel;
+};
+
+#endif // COMPETITORWIDGET_H
diff --git a/widgets/coursewidget.cpp b/widgets/coursewidget.cpp
new file mode 100644
index 0000000..a17d1cf
--- /dev/null
+++ b/widgets/coursewidget.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "coursewidget.h"
+#include "ui_coursewidget.h"
+
+#include "resourcemanager.h"
+#include "mapdelegate.h"
+#include "uniquedelegate.h"
+#include "printdialog.h"
+#include "printoption.h"
+
+CourseWidget::CourseWidget(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::CourseWidget)
+{
+ ui->setupUi(this);
+
+ ui->courseView->setModel(RscMgr::modelHandler()->model(NS_TABLE::COURSE));
+ ui->courseView->hideColumn(NS_COURSE::ID);
+ ui->courseView->setItemDelegateForColumn(NS_COURSE::NAME, new UniqueDelegate(ui->courseView));
+ ui->courseView->setItemDelegateForColumn(NS_COURSE::SEMESTER, new MapDelegate(ui->courseView));
+ ui->courseView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+}
+
+CourseWidget::~CourseWidget()
+{
+ delete ui;
+}
+
+void CourseWidget::add()
+{
+ QMap map;
+ map.insert(NS_COURSE::SEMESTER, NS_SEMESTER::NONE);
+
+ RscMgr::modelHandler()->insertRow(NS_TABLE::COURSE, map);
+
+ const QModelIndex &idx = ui->courseView->model()->index(0, NS_COURSE::NAME);
+
+ ui->courseView->setCurrentIndex(idx);
+ ui->courseView->edit(idx);
+}
+
+void CourseWidget::modify()
+{
+ if (!ui->courseView->currentIndex().isValid())
+ return;
+
+ ui->courseView->edit(ui->courseView->currentIndex());
+}
+
+void CourseWidget::remove()
+{
+ if (!ui->courseView->currentIndex().isValid())
+ return;
+
+ RscMgr::modelHandler()->removeRow(NS_TABLE::COURSE, ui->courseView->currentIndex().row());
+
+ ui->courseView->setFocus();
+ ui->courseView->setCurrentIndex(ui->courseView->model()->index(0, NS_COURSE::NAME));
+}
+
+void CourseWidget::print()
+{
+ PrintOption opt;
+
+ opt.setColumnRemoved(NS_COURSE::ID, true);
+ opt.setColumnHidden(NS_COURSE::ID, true);
+ opt.setMajorColumn(NS_COURSE::NAME);
+ opt.setColumnAggregative(NS_COURSE::SEMESTER, true);
+ opt.setCurrentAggregativeColumn(-1);
+
+ PrintDialog dlg(ui->courseView->model(), &opt);
+ dlg.exec();
+}
diff --git a/widgets/coursewidget.h b/widgets/coursewidget.h
new file mode 100644
index 0000000..aaf098c
--- /dev/null
+++ b/widgets/coursewidget.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef COURSEWIDGET_H
+#define COURSEWIDGET_H
+
+#include
+
+namespace Ui {
+class CourseWidget;
+}
+
+class CourseWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit CourseWidget(QWidget *parent = 0);
+
+ ~CourseWidget();
+
+ void add();
+
+ void modify();
+
+ void remove();
+
+ void print();
+
+private:
+ Ui::CourseWidget *ui;
+};
+
+#endif // COURSEWIDGET_H
diff --git a/widgets/employeewidget.cpp b/widgets/employeewidget.cpp
new file mode 100644
index 0000000..958b739
--- /dev/null
+++ b/widgets/employeewidget.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "employeewidget.h"
+#include "ui_employeewidget.h"
+
+#include "resourcemanager.h"
+#include "uniquedelegate.h"
+#include "mapdelegate.h"
+#include "datedelegate.h"
+#include "printdialog.h"
+#include "printoption.h"
+
+#include
+#include
+
+EmployeeWidget::EmployeeWidget(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::EmployeeWidget)
+{
+ ui->setupUi(this);
+
+ m_employeeProxyModel = new QSortFilterProxyModel(this);
+ m_employeeProxyModel->setSourceModel(RscMgr::modelHandler()->model(NS_TABLE::EMPLOYEE));
+ m_employeeProxyModel->setFilterKeyColumn(NS_EMPLOYEE::JOB);
+
+ ui->employeeView->setModel(m_employeeProxyModel);
+ ui->employeeView->hideColumn(NS_EMPLOYEE::ID);
+ ui->employeeView->hideColumn(NS_EMPLOYEE::JOB);
+ ui->employeeView->setItemDelegateForColumn(NS_EMPLOYEE::FULL_NAME, new UniqueDelegate(ui->employeeView));
+ ui->employeeView->setItemDelegateForColumn(NS_EMPLOYEE::FATHER_NAME, new UniqueDelegate(ui->employeeView));
+ ui->employeeView->setItemDelegateForColumn(NS_EMPLOYEE::GENDER, new MapDelegate(ui->employeeView));
+ ui->employeeView->setItemDelegateForColumn(NS_EMPLOYEE::BIRTH_DATE, new DateDelegate(ui->employeeView));
+ ui->employeeView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
+ ui->employeeView->horizontalHeader()->setSectionResizeMode(NS_EMPLOYEE::FULL_NAME, QHeaderView::Stretch);
+
+ ui->jobView->setModel(RscMgr::modelHandler()->model(NS_TABLE::JOB));
+ ui->jobView->setModelColumn(NS_JOB::NAME);
+ ui->jobView->setCurrentIndex(ui->jobView->model()->index(0, NS_JOB::NAME));
+ ui->jobView->setFixedWidth(ui->jobView->minimumSizeHint().width()
+ + ui->jobView->verticalScrollBar()->sizeHint().width()
+ + 7);
+
+ connect(ui->jobView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(adjustToJob()));
+ connect(ui->jobView->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(refresh()));
+
+ adjustToJob();
+}
+
+EmployeeWidget::~EmployeeWidget()
+{
+ delete ui;
+}
+
+void EmployeeWidget::adjustToJob()
+{
+ m_employeeProxyModel->setFilterRegExp(QString("^%1$").arg(ui->jobView->currentIndex().data().toString()));
+}
+
+void EmployeeWidget::refresh()
+{
+ RscMgr::modelHandler()->model(NS_TABLE::EMPLOYEE)->select();
+ adjustToJob();
+}
+
+void EmployeeWidget::add()
+{
+ if (!ui->jobView->currentIndex().isValid()) {
+ RscMgr::issueMessage(tr("Please select a job first."), false);
+ return;
+ }
+
+ QMap map;
+ map.insert(NS_EMPLOYEE::JOB,
+ ui->jobView->currentIndex()
+ .sibling(ui->jobView->currentIndex().row(), NS_JOB::ID).data());
+
+ RscMgr::modelHandler()->insertRow(NS_TABLE::EMPLOYEE, map);
+
+ const QModelIndex &idx = ui->employeeView->model()->index(0, NS_EMPLOYEE::FULL_NAME);
+
+ ui->employeeView->setCurrentIndex(idx);
+ ui->employeeView->edit(idx);
+}
+
+void EmployeeWidget::modify()
+{
+ if (!ui->employeeView->currentIndex().isValid())
+ return;
+
+ ui->employeeView->edit(ui->employeeView->currentIndex());
+}
+
+void EmployeeWidget::remove()
+{
+ if (!ui->employeeView->currentIndex().isValid())
+ return;
+
+ RscMgr::modelHandler()->removeRow(NS_TABLE::EMPLOYEE, ui->employeeView->currentIndex().row());
+
+ ui->employeeView->setFocus();
+ ui->employeeView->setCurrentIndex(ui->employeeView->model()->index(0, NS_EMPLOYEE::FULL_NAME));
+}
+
+void EmployeeWidget::print()
+{
+ PrintOption opt;
+ opt.setColumnRemoved(NS_EMPLOYEE::ID, true);
+ opt.setColumnHidden(NS_EMPLOYEE::ID, true);
+ opt.setColumnHidden(NS_EMPLOYEE::JOB, true);
+ opt.setMajorColumn(NS_EMPLOYEE::FULL_NAME);
+ opt.setColumnAggregative(NS_EMPLOYEE::GENDER, true);
+ opt.setColumnAggregative(NS_EMPLOYEE::JOB, true);
+ opt.setColumnAggregative(NS_EMPLOYEE::NATIONALITY, true);
+ opt.setColumnAggregative(NS_EMPLOYEE::RESIDENCY, true);
+ opt.setCurrentAggregativeColumn(NS_EMPLOYEE::JOB);
+
+ PrintDialog dlg(m_employeeProxyModel->sourceModel(), &opt);
+
+ dlg.exec();
+}
diff --git a/widgets/employeewidget.h b/widgets/employeewidget.h
new file mode 100644
index 0000000..93793aa
--- /dev/null
+++ b/widgets/employeewidget.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef EMPLOYEEWIDGET_H
+#define EMPLOYEEWIDGET_H
+
+#include
+
+class QSortFilterProxyModel;
+
+namespace Ui {
+class EmployeeWidget;
+}
+
+class EmployeeWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit EmployeeWidget(QWidget *parent = 0);
+
+ ~EmployeeWidget();
+
+ void add();
+
+ void modify();
+
+ void remove();
+
+ void print();
+
+private slots:
+ void adjustToJob();
+
+ void refresh();
+
+private:
+ Ui::EmployeeWidget *ui;
+
+ QSortFilterProxyModel *m_employeeProxyModel;
+};
+
+#endif // EMPLOYEEWIDGET_H
diff --git a/widgets/jobwidget.cpp b/widgets/jobwidget.cpp
new file mode 100644
index 0000000..c51c184
--- /dev/null
+++ b/widgets/jobwidget.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "jobwidget.h"
+#include "ui_jobwidget.h"
+
+#include "resourcemanager.h"
+#include "uniquedelegate.h"
+#include "printdialog.h"
+#include "printoption.h"
+
+JobWidget::JobWidget(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::JobWidget)
+{
+ ui->setupUi(this);
+
+ ui->jobView->setModel(RscMgr::modelHandler()->model(NS_TABLE::JOB));
+ ui->jobView->hideColumn(NS_JOB::ID);
+ ui->jobView->setItemDelegateForColumn(NS_JOB::NAME, new UniqueDelegate(ui->jobView));
+ ui->jobView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+}
+
+JobWidget::~JobWidget()
+{
+ delete ui;
+}
+
+void JobWidget::add()
+{
+ RscMgr::modelHandler()->insertRow(NS_TABLE::JOB);
+
+ const QModelIndex &idx = ui->jobView->model()->index(0, NS_JOB::NAME);
+
+ ui->jobView->setCurrentIndex(idx);
+ ui->jobView->edit(idx);
+}
+
+void JobWidget::modify()
+{
+ if (!ui->jobView->currentIndex().isValid())
+ return;
+
+ ui->jobView->edit(ui->jobView->currentIndex());
+}
+
+void JobWidget::remove()
+{
+ if (!ui->jobView->currentIndex().isValid())
+ return;
+
+ RscMgr::modelHandler()->removeRow(NS_TABLE::JOB, ui->jobView->currentIndex().row());
+
+ ui->jobView->setFocus();
+ ui->jobView->setCurrentIndex(ui->jobView->model()->index(0, NS_JOB::NAME));
+}
+
+void JobWidget::print()
+{
+ PrintOption opt;
+
+ opt.setColumnRemoved(NS_JOB::ID, true);
+ opt.setColumnHidden(NS_JOB::ID, true);
+ opt.setMajorColumn(NS_JOB::NAME);
+
+ PrintDialog dlg(ui->jobView->model(), &opt);
+ dlg.exec();
+}
diff --git a/widgets/jobwidget.h b/widgets/jobwidget.h
new file mode 100644
index 0000000..229d854
--- /dev/null
+++ b/widgets/jobwidget.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef JOBWIDGET_H
+#define JOBWIDGET_H
+
+#include
+
+namespace Ui {
+class JobWidget;
+}
+
+class JobWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit JobWidget(QWidget *parent = 0);
+
+ ~JobWidget();
+
+ void add();
+
+ void modify();
+
+ void remove();
+
+ void print();
+
+private:
+ Ui::JobWidget *ui;
+};
+
+#endif // JOBWIDGET_H
diff --git a/widgets/mainwidget.cpp b/widgets/mainwidget.cpp
new file mode 100644
index 0000000..56529e2
--- /dev/null
+++ b/widgets/mainwidget.cpp
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "mainwidget.h"
+#include "ui_mainwidget.h"
+
+#include "resourcemanager.h"
+#include "classwidget.h"
+#include "coursewidget.h"
+#include "studentwidget.h"
+#include "teacherwidget.h"
+#include "teachingwidget.h"
+#include "resultwidget.h"
+#include "quranwidget.h"
+#include "competitionwidget.h"
+#include "competitorwidget.h"
+#include "jobwidget.h"
+#include "employeewidget.h"
+#include "settingwidget.h"
+
+#include
+
+MainWidget::MainWidget(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::MainWidget)
+{
+ ui->setupUi(this);
+
+ // no need to initialize here beacause a ChangeEvent will be posted during the startup,
+ // however, to for the main widget to show up complete at the very beginning we initialize it here.
+ initialize();
+
+ connect(ui->listWidget, SIGNAL(currentRowChanged(int)),
+ ui->stackedWidget, SLOT(setCurrentIndex(int)));
+
+ connect(ui->listWidget, SIGNAL(currentRowChanged(int)),
+ this, SLOT(setControlFrameVisible(int)));
+
+ setWindowTitle(tr("Furqan"));
+ setWindowFlags(Qt::FramelessWindowHint);
+ setWindowState(Qt::WindowFullScreen);
+}
+
+MainWidget::~MainWidget()
+{
+ delete ui;
+}
+
+void MainWidget::changeEvent(QEvent *e)
+{
+ QWidget::changeEvent(e);
+ switch (e->type()) {
+ case QEvent::LanguageChange:
+ //the layout direction doesn't change automatically (maybe due to a bug),
+ //so we manually change it.
+ setLayoutDirection(RscMgr::dir());
+
+ ui->retranslateUi(this);
+
+ initialize();
+
+ break;
+ default:
+ break;
+ }
+}
+
+void MainWidget::setControlFrameVisible(int index)
+{
+ if (index == ui->listWidget->count() - 1) {
+ ui->controlFrame->hide();
+ } else {
+ ui->controlFrame->show();
+ ui->addButton->setVisible(ui->listWidget->currentRow() != NS_TABLE::RESULT);
+ ui->modifyButton->setVisible(ui->listWidget->currentRow() != NS_TABLE::RESULT);
+ ui->removeButton->setVisible(ui->listWidget->currentRow() != NS_TABLE::RESULT);
+ }
+}
+
+void MainWidget::initialize()
+{
+ allocateWidgets();
+ populateListWidget();
+ populateStackWidget();
+
+ ui->listWidget->setCurrentRow(0);
+ ui->stackedWidget->setCurrentIndex(0);
+
+ ui->listWidget->setMinimumWidth(ui->listWidget->sizeHintForColumn(0) + 7);
+}
+
+void MainWidget::allocateWidgets()
+{
+ m_classWidget = new ClassWidget;
+ m_courseWidget = new CourseWidget;
+ m_studentWidget = new StudentWidget;
+ m_teacherWidget = new TeacherWidget;
+ m_teachingWidget = new TeachingWidget;
+ m_resultWidget = new ResultWidget;
+ m_quranWidget = new QuranWidget;
+ m_competitionWidget = new CompetitionWidget;
+ m_competitorWidget = new CompetitorWidget;
+ m_jobWidget = new JobWidget;
+ m_employeeWidget = new EmployeeWidget;
+ m_settingWidget = new SettingWidget;
+}
+
+void MainWidget::populateListWidget()
+{
+ //the listWidget might contain items,
+ //actually this function would be invoked once the user requests to change language.
+ ui->listWidget->clear();
+
+ ui->listWidget->insertItem(NS_TABLE::CLASS, tr("Classes"));
+ ui->listWidget->insertItem(NS_TABLE::COURSE, tr("Courses"));
+ ui->listWidget->insertItem(NS_TABLE::STUDENT, tr("Students"));
+ ui->listWidget->insertItem(NS_TABLE::TEACHER, tr("Teachers"));
+ ui->listWidget->insertItem(NS_TABLE::TEACHING, tr("Teaching"));
+ ui->listWidget->insertItem(NS_TABLE::RESULT, tr("Results of Courses"));
+ ui->listWidget->insertItem(NS_TABLE::QURAN, tr("Studies of Quran"));
+ ui->listWidget->insertItem(NS_TABLE::COMPETITION, tr("Competitions"));
+ ui->listWidget->insertItem(NS_TABLE::COMPETITOR, tr("Competitors"));
+ ui->listWidget->insertItem(NS_TABLE::JOB, tr("Jobs"));
+ ui->listWidget->insertItem(NS_TABLE::EMPLOYEE, tr("Employees"));
+ ui->listWidget->addItem(tr("Setting"));
+}
+
+void MainWidget::populateStackWidget()
+{
+ while (ui->stackedWidget->count() > 0) {
+ QWidget *page = ui->stackedWidget->widget(ui->stackedWidget->count() - 1);
+ ui->stackedWidget->removeWidget(page);
+ page->close();
+ page->deleteLater();
+ }
+
+ ui->stackedWidget->insertWidget(NS_TABLE::CLASS, m_classWidget);
+ ui->stackedWidget->insertWidget(NS_TABLE::COURSE, m_courseWidget);
+ ui->stackedWidget->insertWidget(NS_TABLE::STUDENT, m_studentWidget);
+ ui->stackedWidget->insertWidget(NS_TABLE::TEACHER, m_teacherWidget);
+ ui->stackedWidget->insertWidget(NS_TABLE::TEACHING, m_teachingWidget);
+ ui->stackedWidget->insertWidget(NS_TABLE::RESULT, m_resultWidget);
+ ui->stackedWidget->insertWidget(NS_TABLE::QURAN, m_quranWidget);
+ ui->stackedWidget->insertWidget(NS_TABLE::COMPETITION, m_competitionWidget);
+ ui->stackedWidget->insertWidget(NS_TABLE::COMPETITOR, m_competitorWidget);
+ ui->stackedWidget->insertWidget(NS_TABLE::JOB, m_jobWidget);
+ ui->stackedWidget->insertWidget(NS_TABLE::EMPLOYEE, m_employeeWidget);
+ ui->stackedWidget->addWidget(m_settingWidget);
+}
+
+// the result case is excluded because the database's trigger who inserts the corresponding
+// rows when a new course or student is added to the database.
+void MainWidget::on_addButton_clicked()
+{
+ switch (ui->listWidget->currentRow()) {
+ case NS_TABLE::CLASS: m_classWidget->add(); break;
+ case NS_TABLE::COURSE: m_courseWidget->add(); break;
+ case NS_TABLE::STUDENT: m_studentWidget->add(); break;
+ case NS_TABLE::TEACHER: m_teacherWidget->add(); break;
+ case NS_TABLE::TEACHING: m_teachingWidget->add(); break;
+ // case NS_TABLE::RESULT: mResultWidget->add(); break;
+ case NS_TABLE::QURAN: m_quranWidget->add(); break;
+ case NS_TABLE::COMPETITION: m_competitionWidget->add(); break;
+ case NS_TABLE::COMPETITOR: m_competitorWidget->add(); break;
+ case NS_TABLE::JOB: m_jobWidget->add(); break;
+ case NS_TABLE::EMPLOYEE: m_employeeWidget->add(); break;
+
+ default:
+ break;
+ }
+}
+
+void MainWidget::on_modifyButton_clicked()
+{
+ switch (ui->listWidget->currentRow()) {
+ case NS_TABLE::CLASS: m_classWidget->modify(); break;
+ case NS_TABLE::COURSE: m_courseWidget->modify(); break;
+ case NS_TABLE::STUDENT: m_studentWidget->modify(); break;
+ case NS_TABLE::TEACHER: m_teacherWidget->modify(); break;
+ case NS_TABLE::TEACHING: m_teachingWidget->modify(); break;
+ // case NS_TABLE::RESULT: mResultWidget->modify(); break;
+ case NS_TABLE::QURAN: m_quranWidget->modify(); break;
+ case NS_TABLE::COMPETITION: m_competitionWidget->modify(); break;
+ case NS_TABLE::COMPETITOR: m_competitorWidget->modify(); break;
+ case NS_TABLE::JOB: m_jobWidget->modify(); break;
+ case NS_TABLE::EMPLOYEE: m_employeeWidget->modify(); break;
+
+ default:
+ break;
+ }
+}
+
+void MainWidget::on_removeButton_clicked()
+{
+ switch (ui->listWidget->currentRow()) {
+ case NS_TABLE::CLASS: m_classWidget->remove(); break;
+ case NS_TABLE::COURSE: m_courseWidget->remove(); break;
+ case NS_TABLE::STUDENT: m_studentWidget->remove(); break;
+ case NS_TABLE::TEACHER: m_teacherWidget->remove(); break;
+ case NS_TABLE::TEACHING: m_teachingWidget->remove(); break;
+ // case NS_TABLE::RESULT: mResultWidget->remove(); break;
+ case NS_TABLE::QURAN: m_quranWidget->remove(); break;
+ case NS_TABLE::COMPETITION: m_competitionWidget->remove(); break;
+ case NS_TABLE::COMPETITOR: m_competitorWidget->remove(); break;
+ case NS_TABLE::JOB: m_jobWidget->remove(); break;
+ case NS_TABLE::EMPLOYEE: m_employeeWidget->remove(); break;
+
+ default:
+ break;
+ }
+}
+
+void MainWidget::on_printButton_clicked()
+{
+ switch (ui->listWidget->currentRow()) {
+ case NS_TABLE::CLASS: m_classWidget->print(); break;
+ case NS_TABLE::COURSE: m_courseWidget->print(); break;
+ case NS_TABLE::STUDENT: m_studentWidget->print(); break;
+ case NS_TABLE::TEACHER: m_teacherWidget->print(); break;
+ case NS_TABLE::TEACHING: m_teachingWidget->print(); break;
+ case NS_TABLE::RESULT: m_resultWidget->print(); break;
+ case NS_TABLE::QURAN: m_quranWidget->print(); break;
+ case NS_TABLE::COMPETITION: m_competitionWidget->print(); break;
+ case NS_TABLE::COMPETITOR: m_competitorWidget->print(); break;
+ case NS_TABLE::JOB: m_jobWidget->print(); break;
+ case NS_TABLE::EMPLOYEE: m_employeeWidget->print(); break;
+
+ default:
+ break;
+ }
+}
+
+void MainWidget::on_furqanButton_clicked()
+{
+ QSplashScreen *splashScreen = RscMgr::createSplashScreen();
+ splashScreen->show();
+}
diff --git a/widgets/mainwidget.h b/widgets/mainwidget.h
new file mode 100644
index 0000000..1b34869
--- /dev/null
+++ b/widgets/mainwidget.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef MAINWIDGET_H
+#define MAINWIDGET_H
+
+#include
+
+class ClassWidget;
+class CourseWidget;
+class StudentWidget;
+class TeacherWidget;
+class TeachingWidget;
+class ResultWidget;
+class QuranWidget;
+class CompetitionWidget;
+class CompetitorWidget;
+class JobWidget;
+class EmployeeWidget;
+class SettingWidget;
+
+class QSqlTableModel;
+
+namespace Ui {
+class MainWidget;
+}
+
+class MainWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit MainWidget(QWidget *parent = 0);
+ ~MainWidget();
+
+protected:
+ void changeEvent(QEvent *);
+
+private slots:
+ void initialize();
+
+ void allocateWidgets();
+
+ void populateListWidget();
+
+ void populateStackWidget();
+
+ void setControlFrameVisible(int);
+
+ void on_addButton_clicked();
+
+ void on_modifyButton_clicked();
+
+ void on_removeButton_clicked();
+
+ void on_printButton_clicked();
+
+ void on_furqanButton_clicked();
+
+private:
+ Ui::MainWidget *ui;
+
+ ClassWidget *m_classWidget;
+ CourseWidget *m_courseWidget;
+ StudentWidget *m_studentWidget;
+ TeacherWidget *m_teacherWidget;
+ TeachingWidget *m_teachingWidget;
+ ResultWidget *m_resultWidget;
+ QuranWidget *m_quranWidget;
+ CompetitionWidget *m_competitionWidget;
+ CompetitorWidget *m_competitorWidget;
+ JobWidget *m_jobWidget;
+ EmployeeWidget *m_employeeWidget;
+ SettingWidget *m_settingWidget;
+};
+
+#endif // MAINWIDGET_H
diff --git a/widgets/printdialog.cpp b/widgets/printdialog.cpp
new file mode 100644
index 0000000..81ab152
--- /dev/null
+++ b/widgets/printdialog.cpp
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "printdialog.h"
+
+#include "resourcemanager.h"
+#include "texteditor.h"
+#include "printOption.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+PrintDialog::PrintDialog(QAbstractItemModel *model, PrintOption *printOption, QWidget *parent) :
+ QDialog(parent),
+ m_model(model),
+ m_printOption(printOption),
+ m_preambleTextEdit(new TextEditor),
+ m_commentaryTextEdit(new TextEditor),
+ m_tableFontNameCombo(new QFontComboBox),
+ m_tableFontSizeCombo(new QComboBox),
+ m_tableColorButton(new QPushButton),
+ m_columnVisibilityListWidget(new QListWidget),
+ m_aggregativeColumnListWidget(new QListWidget),
+ m_aggregativeColumnEntryListWidget(new QListWidget),
+ m_rowVisibilityListWidget(new QListWidget),
+ m_tabWidget(new QTabWidget),
+ m_preview(new QPrintPreviewWidget(RscMgr::printHandler()->previewPrinter())),
+ m_buttonGroup(new QButtonGroup(this)),
+ m_zoomIn(new QPushButton),
+ m_zoomOut(new QPushButton),
+ m_printButton(new QPushButton(tr("Print"))),
+ m_closeButton(new QPushButton(tr("Close")))
+{
+ setWindowTitle(tr("Print"));
+ setWindowFlags(Qt::FramelessWindowHint);
+
+ setLayoutDirection(RscMgr::dir());
+
+ initialize();
+ createLayouts();
+ loadSettings();
+ createConnections();
+
+ m_tabWidget->setFixedWidth(m_columnVisibilityListWidget->sizeHint().width());
+ m_preview->setFixedWidth(m_preview->width());
+
+ showFullScreen();
+}
+
+PrintDialog::~PrintDialog()
+{}
+
+void PrintDialog::print() const
+{
+ m_printOption->setPreamble(m_preambleTextEdit->toHtml());
+ m_printOption->setCommentary(m_commentaryTextEdit->toHtml());
+
+ RscMgr::printHandler()->print(m_model, m_printOption, RscMgr::printHandler()->nativePrinter());
+}
+
+void PrintDialog::preview(QPrinter *printer) const
+{
+ m_printOption->setPreamble(m_preambleTextEdit->toHtml());
+ m_printOption->setCommentary(m_commentaryTextEdit->toHtml());
+
+ RscMgr::printHandler()->print(m_model, m_printOption, printer);
+}
+
+void PrintDialog::initialize()
+{
+ m_tableFontSizeCombo->setEditable(true);
+
+ QFontDatabase db;
+ foreach(int size, db.standardSizes())
+ m_tableFontSizeCombo->addItem(QString::number(size));
+
+ m_tableColorButton->setFlat(true);
+ m_tableColorButton->setMaximumWidth(25);
+ m_tableColorButton->setCursor(Qt::PointingHandCursor);
+ m_tableColorButton->setStyleSheet(QString("border: 1px solid black; background-color: %1;").arg(RscMgr::settingHandler()->tableFontColor()));
+
+ m_tabWidget->setTabPosition(RscMgr::dir() == Qt::RightToLeft ? QTabWidget::East : QTabWidget::West);
+ m_tabWidget->addTab(m_columnVisibilityListWidget, tr("Shown Columns"));
+ m_tabWidget->addTab(m_aggregativeColumnListWidget, tr("Aggregative Columns"));
+ m_tabWidget->addTab(m_aggregativeColumnEntryListWidget, tr("Aggragative Column Entries"));
+ m_tabWidget->addTab(m_rowVisibilityListWidget, tr("Shown Rows"));
+
+ for (int i = 0; i < m_model->columnCount(); ++i) {
+ if (m_printOption->isColumnRemoved(i))
+ continue;
+
+ QListWidgetItem *item = new QListWidgetItem(m_model->headerData(i, Qt::Horizontal).toString());
+ item->setCheckState(m_printOption->isColumnHidden(i) ? Qt::Unchecked : Qt::Checked);
+ item->setData(Qt::UserRole, i);
+ item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
+
+ //if it's the name column, then disable it.
+ if (i == m_printOption->majorColumn())
+ item->setFlags(Qt::NoItemFlags);
+
+ m_columnVisibilityListWidget->addItem(item);
+ }
+
+ QRadioButton *noneRadioButton = new QRadioButton(tr("None"));
+ noneRadioButton->setChecked(true);
+ m_buttonGroup->addButton(noneRadioButton);
+ QListWidgetItem *item = new QListWidgetItem;
+ item->setFlags(Qt::ItemIsEnabled);
+ m_aggregativeColumnListWidget->addItem(item);
+ m_aggregativeColumnListWidget->setItemWidget(item, noneRadioButton);
+
+ for (int i = 0; i < m_model->columnCount(); ++i) {
+ if (m_printOption->isColumnAggregative(i)) {
+ QRadioButton *radioButton = new QRadioButton(m_model->headerData(i, Qt::Horizontal).toString());
+ m_buttonGroup->addButton(radioButton);
+ radioButton->setChecked(i == m_printOption->currentAggregativeColumn());
+ QListWidgetItem *item = new QListWidgetItem;
+ item->setFlags(Qt::ItemIsEnabled);
+ item->setData(Qt::UserRole, i);
+ m_aggregativeColumnListWidget->addItem(item);
+ m_aggregativeColumnListWidget->setItemWidget(item, radioButton);
+ }
+ }
+
+ emit currentAggregationChanged(m_buttonGroup->checkedButton());
+}
+
+void PrintDialog::createLayouts()
+{
+ QString styleSheet = "QFrame {"
+ "background: lightgray;"
+ "border: 1px solid black;"
+ "padding: 1px;"
+ "}"
+ "QPushButton {"
+ " padding: 3px;"
+ "}"
+ "QPushButton:hover {"
+ " color: white;"
+ " border: 1px solid gray;"
+ "}";
+
+ QFrame *zoomFrame = new QFrame;
+ zoomFrame->setStyleSheet(styleSheet);
+
+ m_zoomIn->setIcon(QIcon(":/zoom-in"));
+ m_zoomIn->setFlat(true);
+ m_zoomIn->setIconSize(QSize(24, 24));
+ m_zoomIn->setCursor(QCursor(Qt::PointingHandCursor));
+
+ m_zoomOut->setIcon(QIcon(":/zoom-out"));
+ m_zoomOut->setFlat(true);
+ m_zoomOut->setIconSize(QSize(24, 24));
+ m_zoomOut->setCursor(QCursor(Qt::PointingHandCursor));
+
+ m_preview->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ m_preview->fitToWidth();
+
+ QFrame *printFrame = new QFrame;
+ printFrame->setStyleSheet(styleSheet);
+
+ m_printButton->setFlat(true);
+ m_printButton->setIcon(QIcon(":/printer"));
+ m_printButton->setIconSize(QSize(32, 32));
+ m_printButton->setCursor(QCursor(Qt::PointingHandCursor));
+
+ m_closeButton->setFlat(true);
+ m_closeButton->setIcon(RscMgr::dir() == Qt::LeftToRight ? QIcon(":/close-ltr") : QIcon(":/close-rtl"));
+ m_closeButton->setIconSize(QSize(32, 32));
+ m_closeButton->setCursor(QCursor(Qt::PointingHandCursor));
+
+ QHBoxLayout *tableHLayout = new QHBoxLayout;
+ tableHLayout->addWidget(m_tableFontNameCombo);
+ tableHLayout->addWidget(m_tableFontSizeCombo);
+ tableHLayout->addWidget(m_tableColorButton);
+ tableHLayout->addStretch();
+
+ QVBoxLayout *editVLayout = new QVBoxLayout;
+ editVLayout->addWidget(new QLabel(QString("%1").arg(tr("Preamble"))));
+ editVLayout->addWidget(m_preambleTextEdit);
+ editVLayout->addSpacing(7);
+ editVLayout->addWidget(new QLabel(QString("%1").arg(tr("Table"))));
+ editVLayout->addLayout(tableHLayout);
+ editVLayout->addSpacing(7);
+ editVLayout->addWidget(new QLabel(QString("%1").arg(tr("Commentary"))));
+ editVLayout->addWidget(m_commentaryTextEdit);
+
+ QHBoxLayout *zoomHLayout = new QHBoxLayout(zoomFrame);
+ zoomHLayout->setContentsMargins(QMargins(0, 0, 0, 0));
+ zoomHLayout->setSpacing(3);
+ zoomHLayout->addStretch();
+ zoomHLayout->addWidget(m_zoomIn);
+ zoomHLayout->addWidget(m_zoomOut);
+
+ QVBoxLayout *previewVLayout = new QVBoxLayout;
+ previewVLayout->setSpacing(1);
+ previewVLayout->addWidget(m_preview);
+ previewVLayout->addWidget(zoomFrame);
+
+ QHBoxLayout *mainHLayout = new QHBoxLayout;
+ mainHLayout->addLayout(editVLayout);
+ mainHLayout->addWidget(m_tabWidget);
+ mainHLayout->addLayout(previewVLayout);
+
+ QHBoxLayout *printHLayout = new QHBoxLayout(printFrame);
+ printHLayout->setContentsMargins(QMargins(0, 0, 0, 0));
+ printHLayout->setSpacing(15);
+ printHLayout->addStretch();
+ printHLayout->addWidget(m_printButton);
+ printHLayout->addWidget(m_closeButton);
+
+ QVBoxLayout *mainVLayout = new QVBoxLayout(this);
+ mainVLayout->addWidget(printFrame);
+ mainVLayout->addLayout(mainHLayout);
+}
+
+void PrintDialog::createConnections()
+{
+ connect(m_preambleTextEdit, SIGNAL(fontFamilyChanged(QString)), RscMgr::settingHandler(), SLOT(setPreambleFontFamily(QString)));
+ connect(m_preambleTextEdit, SIGNAL(fontSizeChanged(QString)), RscMgr::settingHandler(), SLOT(setPreambleFontSize(QString)));
+ connect(m_preambleTextEdit, SIGNAL(fontColorChanged(QString)), RscMgr::settingHandler(), SLOT(setPreambleFontColor(QString)));
+
+ connect(m_commentaryTextEdit, SIGNAL(fontFamilyChanged(QString)), RscMgr::settingHandler(), SLOT(setCommentaryFontFamily(QString)));
+ connect(m_commentaryTextEdit, SIGNAL(fontSizeChanged(QString)), RscMgr::settingHandler(), SLOT(setCommentaryFontSize(QString)));
+ connect(m_commentaryTextEdit, SIGNAL(fontColorChanged(QString)), RscMgr::settingHandler(), SLOT(setCommentaryFontColor(QString)));
+
+ connect(m_tableFontNameCombo, SIGNAL(currentIndexChanged(QString)), RscMgr::settingHandler(), SLOT(setTableFontFamily(QString)));
+ connect(m_tableFontSizeCombo, SIGNAL(currentTextChanged(QString)), RscMgr::settingHandler(), SLOT(setTableFontSize(QString)));
+ connect(m_tableColorButton, SIGNAL(clicked()), SLOT(setTableFontColor()));
+
+ connect(m_buttonGroup, SIGNAL(buttonClicked(QAbstractButton*)), SLOT(currentAggregationChanged(QAbstractButton*)));
+
+ connect(m_columnVisibilityListWidget, SIGNAL(itemChanged(QListWidgetItem*)), SLOT(columnVisibilityChanged(QListWidgetItem*)));
+ connect(m_aggregativeColumnEntryListWidget, SIGNAL(itemChanged(QListWidgetItem*)), SLOT(aggregationEntryVisibilityChanged(QListWidgetItem*)));
+ connect(m_rowVisibilityListWidget, SIGNAL(itemChanged(QListWidgetItem*)), SLOT(rowVisibilityChanged(QListWidgetItem*)));
+
+ connect(m_buttonGroup, SIGNAL(buttonClicked(QAbstractButton*)), m_preview, SLOT(updatePreview()));
+ connect(m_columnVisibilityListWidget, SIGNAL(itemChanged(QListWidgetItem*)), m_preview, SLOT(updatePreview()));
+ connect(m_aggregativeColumnEntryListWidget, SIGNAL(itemChanged(QListWidgetItem*)), m_preview, SLOT(updatePreview()));
+ connect(m_rowVisibilityListWidget, SIGNAL(itemChanged(QListWidgetItem*)), m_preview, SLOT(updatePreview()));
+ connect(m_preambleTextEdit, SIGNAL(textChanged()), m_preview, SLOT(updatePreview()));
+ connect(m_commentaryTextEdit, SIGNAL(textChanged()), m_preview, SLOT(updatePreview()));
+ connect(m_tableFontNameCombo, SIGNAL(currentFontChanged(QFont)), m_preview, SLOT(updatePreview()));
+ connect(m_tableFontSizeCombo, SIGNAL(currentIndexChanged(int)), m_preview, SLOT(updatePreview()));
+ connect(RscMgr::settingHandler(), SIGNAL(settingChanged()), m_preview, SLOT(updatePreview()));
+
+ connect(m_preview, SIGNAL(paintRequested(QPrinter*)), SLOT(preview(QPrinter*)));
+
+ connect(m_zoomIn, SIGNAL(clicked()), m_preview, SLOT(zoomIn()));
+ connect(m_zoomOut, SIGNAL(clicked()), m_preview, SLOT(zoomOut()));
+
+ connect(m_printButton, SIGNAL(clicked()), SLOT(print()));
+ connect(m_printButton, SIGNAL(clicked()), SLOT(accept()));
+ connect(m_closeButton, SIGNAL(clicked()), SLOT(reject()));
+
+}
+
+void PrintDialog::loadSettings()
+{
+ m_preambleTextEdit->setFontFamily(RscMgr::settingHandler()->preambleFontFamily());
+ m_preambleTextEdit->setFontColor(RscMgr::settingHandler()->preambleFontColor());
+ m_preambleTextEdit->setFontSize(RscMgr::settingHandler()->preambleFontSize());
+
+ m_commentaryTextEdit->setFontFamily(RscMgr::settingHandler()->commentaryFontFamily());
+ m_commentaryTextEdit->setFontColor(RscMgr::settingHandler()->commentaryFontColor());
+ m_commentaryTextEdit->setFontSize(RscMgr::settingHandler()->commentaryFontSize());
+
+ m_tableFontNameCombo->setCurrentText(RscMgr::settingHandler()->tableFontFamily());
+
+ m_tableFontSizeCombo->setCurrentText(RscMgr::settingHandler()->tableFontSize());
+
+}
+
+void PrintDialog::setTableFontColor() const
+{
+ QColor color = QColorDialog::getColor(Qt::black);
+ if (!color.isValid())
+ return;
+
+ RscMgr::settingHandler()->setTableFontColor(color.name());
+ m_tableColorButton->setStyleSheet(QString("border: 1px solid black; background-color: %1;").arg(color.name(QColor::HexRgb)));
+}
+
+void PrintDialog::columnVisibilityChanged(QListWidgetItem *item)
+{
+ //the addition by on is for the ID column of each table.
+ m_printOption->setColumnHidden(item->data(Qt::UserRole).toInt(), item->checkState() == Qt::Unchecked);
+}
+
+void PrintDialog::rowVisibilityChanged(QListWidgetItem *item)
+{
+ m_printOption->setRowHidden(item->data(Qt::UserRole).toInt(), item->checkState() == Qt::Unchecked);
+}
+
+void PrintDialog::currentAggregationChanged(QAbstractButton *button)
+{
+ m_aggregativeColumnEntryListWidget->clear();
+
+ for (int i = 0; i < m_model->columnCount(); ++i) {
+ if (m_model->headerData(i, Qt::Horizontal).toString() == button->text()) {
+ m_printOption->setCurrentAggregativeColumn(i);
+
+ for (int j = 0; j < m_model->rowCount(); ++j) {
+ const QString &itemText = m_model->index(j, i).data().toString();
+
+ QList itemList = m_aggregativeColumnEntryListWidget->findItems(itemText, Qt::MatchExactly);
+ if (itemList.isEmpty()) {
+ QListWidgetItem *item = new QListWidgetItem(itemText);
+ item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
+ item->setCheckState(Qt::Checked);
+ m_aggregativeColumnEntryListWidget->addItem(item);
+ }
+ }
+
+ emit aggregationEntryVisibilityChanged(0);
+
+ return;
+ }
+ }
+
+ m_printOption->setCurrentAggregativeColumn(-1);
+
+ emit aggregationEntryVisibilityChanged(0);
+}
+
+void PrintDialog::aggregationEntryVisibilityChanged(QListWidgetItem *item)
+{
+ if (item)
+ m_printOption->setAggregationEntryHidden(item->text(), item->checkState() == Qt::Unchecked);
+
+ m_rowVisibilityListWidget->clear();
+
+ if (m_printOption->currentAggregativeColumn() >= 0)
+ m_model->sort(m_printOption->currentAggregativeColumn(), Qt::AscendingOrder);
+ else
+ m_model->sort(0, Qt::AscendingOrder);
+
+ for (int i = 0; i < m_model->rowCount(); ++i) {
+ if (m_printOption->currentAggregativeColumn() >= 0) {
+ const QString &entry = m_model->index(i, m_printOption->currentAggregativeColumn()).data().toString();
+ if (m_printOption->isAggregationEntryHidden(entry))
+ continue;
+ }
+ QListWidgetItem *rowItem = new QListWidgetItem(QString("[%1] %2").arg(i + 1).arg(m_model->index(i, m_printOption->majorColumn()).data().toString()));
+ rowItem->setCheckState(m_printOption->isRowHidden(m_model->index(i, 0).data().toInt()) ? Qt::Unchecked : Qt::Checked);
+ rowItem->setData(Qt::UserRole, m_model->index(i, 0).data().toInt());
+ rowItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
+ m_rowVisibilityListWidget->addItem(rowItem);
+ }
+}
diff --git a/widgets/printdialog.h b/widgets/printdialog.h
new file mode 100644
index 0000000..93ba104
--- /dev/null
+++ b/widgets/printdialog.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef PRINTDIALOG_H
+#define PRINTDIALOG_H
+
+#include
+
+namespace Ui {
+class PrintDialog;
+}
+
+class TextEditor;
+class PrintOption;
+
+class QAbstractItemModel;
+class QPrintPreviewWidget;
+class QPrinter;
+class QListWidget;
+class QTabWidget;
+class QButtonGroup;
+class QListWidgetItem;
+class QAbstractButton;
+class QFontComboBox;
+class QComboBox;
+
+class PrintDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit PrintDialog(QAbstractItemModel *model, PrintOption *printOption, QWidget *parent = 0);
+ ~PrintDialog();
+
+private slots:
+ void print() const;
+
+ void preview(QPrinter *) const;
+
+ void initialize();
+ void createLayouts();
+ void createConnections();
+ void loadSettings();
+
+ void setTableFontColor() const;
+
+ void columnVisibilityChanged(QListWidgetItem *);
+
+ void rowVisibilityChanged(QListWidgetItem *);
+
+ void currentAggregationChanged(QAbstractButton *);
+
+ void aggregationEntryVisibilityChanged(QListWidgetItem *);
+
+private:
+ QAbstractItemModel *m_model;
+
+ PrintOption *m_printOption;
+
+ TextEditor *m_preambleTextEdit;
+ TextEditor *m_commentaryTextEdit;
+
+ QFontComboBox *m_tableFontNameCombo;
+ QComboBox *m_tableFontSizeCombo;
+ QPushButton *m_tableColorButton;
+
+ QListWidget *m_columnVisibilityListWidget;
+ QListWidget *m_aggregativeColumnListWidget;
+ QListWidget *m_aggregativeColumnEntryListWidget;
+ QListWidget *m_rowVisibilityListWidget;
+
+ QTabWidget *m_tabWidget;
+
+ QPrintPreviewWidget *m_preview;
+
+ QButtonGroup *m_buttonGroup;
+
+ QPushButton *m_zoomIn;
+ QPushButton *m_zoomOut;
+ QPushButton *m_printButton;
+ QPushButton *m_closeButton;
+};
+
+#endif // PRINTDIALOG_H
diff --git a/widgets/quranwidget.cpp b/widgets/quranwidget.cpp
new file mode 100644
index 0000000..7c571ab
--- /dev/null
+++ b/widgets/quranwidget.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "quranwidget.h"
+#include "ui_quranwidget.h"
+
+#include "resourcemanager.h"
+#include "mapdelegate.h"
+#include "numericdelegate.h"
+#include "datedelegate.h"
+#include "printdialog.h"
+#include "printoption.h"
+
+#include
+#include
+
+QuranWidget::QuranWidget(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::QuranWidget)
+{
+ ui->setupUi(this);
+
+ m_quranProxyModel = new QSortFilterProxyModel(this);
+ m_quranProxyModel->setSourceModel(RscMgr::modelHandler()->model(NS_TABLE::QURAN));
+ m_quranProxyModel->setFilterKeyColumn(NS_QURAN::STUDENT);
+
+ ui->quranView->setModel(m_quranProxyModel);
+ ui->quranView->hideColumn(NS_QURAN::ID);
+ ui->quranView->hideColumn(NS_QURAN::STUDENT);
+ ui->quranView->setItemDelegateForColumn(NS_QURAN::RECITAL_TYPE, new MapDelegate(ui->quranView));
+ ui->quranView->setItemDelegateForColumn(NS_QURAN::FROM_PAGE, new NumericDelegate(new QIntValidator(0, 604, this), this));
+ ui->quranView->setItemDelegateForColumn(NS_QURAN::TO_PAGE, new NumericDelegate(new QIntValidator(0, 604, this), this));
+ ui->quranView->setItemDelegateForColumn(NS_QURAN::DATE, new DateDelegate(ui->quranView));
+ ui->quranView->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents);
+ ui->quranView->horizontalHeader()->setSectionResizeMode(NS_QURAN::RECITAL_TYPE, QHeaderView::Stretch);
+
+ ui->studentView->setModel(RscMgr::modelHandler()->model(NS_TABLE::STUDENT));
+ ui->studentView->setModelColumn(NS_STUDENT::FULL_NAME);
+ ui->studentView->setCurrentIndex(ui->studentView->model()->index(0, NS_STUDENT::FULL_NAME));
+ ui->studentView->setFixedWidth(ui->studentView->minimumSizeHint().width()
+ + ui->studentView->verticalScrollBar()->sizeHint().width()
+ + 7);
+
+ connect(ui->studentView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(adjustToStudent()));
+ //maintaining the foreign key's relations between tables
+ connect(ui->studentView->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(refresh()));
+ connect(RscMgr::modelHandler()->model(NS_TABLE::CLASS), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(refresh()));
+
+ adjustToStudent();
+}
+
+QuranWidget::~QuranWidget()
+{
+ delete ui;
+}
+
+void QuranWidget::adjustToStudent()
+{
+ m_quranProxyModel->setFilterRegExp(QString("^%1$").arg(ui->studentView->currentIndex().data().toString()));
+}
+
+void QuranWidget::refresh()
+{
+ RscMgr::modelHandler()->model(NS_TABLE::QURAN)->select();
+ adjustToStudent();
+}
+
+void QuranWidget::add()
+{
+ if (!ui->studentView->currentIndex().isValid()) {
+ RscMgr::issueMessage(tr("Please select a student first."), false);
+ return;
+ }
+
+ QMap map;
+ map.insert(NS_QURAN::STUDENT,
+ ui->studentView->currentIndex()
+ .sibling(ui->studentView->currentIndex().row(), NS_STUDENT::ID).data());
+
+ RscMgr::modelHandler()->insertRow(NS_TABLE::QURAN, map);
+
+ const QModelIndex &idx = ui->quranView->model()->index(0, NS_QURAN::RECITAL_TYPE);
+
+ ui->quranView->setCurrentIndex(idx);
+ ui->quranView->edit(idx);
+}
+
+void QuranWidget::modify()
+{
+ if (!ui->quranView->currentIndex().isValid())
+ return;
+
+ ui->quranView->edit(ui->quranView->currentIndex());
+}
+
+void QuranWidget::remove()
+{
+ if (!ui->quranView->currentIndex().isValid())
+ return;
+
+ RscMgr::modelHandler()->removeRow(NS_TABLE::QURAN, ui->quranView->currentIndex().row());
+
+ ui->quranView->setFocus();
+ ui->quranView->setCurrentIndex(ui->quranView->model()->index(0, NS_QURAN::STUDENT));
+}
+
+void QuranWidget::print()
+{
+ PrintOption opt;
+ opt.setColumnRemoved(NS_QURAN::ID, true);
+ opt.setColumnHidden(NS_QURAN::ID, true);
+ opt.setMajorColumn(NS_QURAN::STUDENT);
+ opt.setColumnAggregative(NS_QURAN::DATE, true);
+ opt.setColumnAggregative(NS_QURAN::RECITAL_TYPE, true);
+ opt.setCurrentAggregativeColumn(-1);
+
+ PrintDialog dlg(m_quranProxyModel->sourceModel(), &opt);
+
+ dlg.exec();
+}
diff --git a/widgets/quranwidget.h b/widgets/quranwidget.h
new file mode 100644
index 0000000..774d8b6
--- /dev/null
+++ b/widgets/quranwidget.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef QURANWIDGET_H
+#define QURANWIDGET_H
+
+#include
+
+class QSortFilterProxyModel;
+
+namespace Ui {
+class QuranWidget;
+}
+
+class QuranWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit QuranWidget(QWidget *parent = 0);
+
+ ~QuranWidget();
+
+ void add();
+
+ void modify();
+
+ void remove();
+
+ void print();
+
+private slots:
+ void adjustToStudent();
+
+ void refresh();
+
+private:
+ Ui::QuranWidget *ui;
+
+ QSortFilterProxyModel *m_quranProxyModel;
+};
+
+#endif // QURANWIDGET_H
diff --git a/widgets/resultwidget.cpp b/widgets/resultwidget.cpp
new file mode 100644
index 0000000..32dcaef
--- /dev/null
+++ b/widgets/resultwidget.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "resultwidget.h"
+#include "ui_resultwidget.h"
+
+#include "resourcemanager.h"
+#include "sqldelegate.h"
+#include "numericdelegate.h"
+#include "printdialog.h"
+#include "printoption.h"
+
+#include
+#include
+
+ResultWidget::ResultWidget(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::ResultWidget)
+{
+ ui->setupUi(this);
+
+ m_resultProxyModel = new QSortFilterProxyModel(this);
+ m_resultProxyModel->setSourceModel(RscMgr::modelHandler()->model(NS_TABLE::RESULT));
+ m_resultProxyModel->setFilterKeyColumn(NS_RESULT::COURSE);
+
+ ui->resultView->setModel(m_resultProxyModel);
+ ui->resultView->hideColumn(NS_RESULT::ID);
+ ui->resultView->hideColumn(NS_RESULT::COURSE);
+ ui->resultView->setItemDelegateForColumn(NS_RESULT::STUDENT, new SqlDelegate(false, ui->resultView));
+
+ QDoubleValidator *validator = new QDoubleValidator(0, 100, 2, this);
+ validator->setNotation(QDoubleValidator::StandardNotation);
+
+ ui->resultView->setItemDelegateForColumn(NS_RESULT::RESULT, new NumericDelegate(validator, this));
+ ui->resultView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+
+ ui->courseView->setModel(RscMgr::modelHandler()->model(NS_TABLE::COURSE));
+ ui->courseView->setModelColumn(NS_COURSE::NAME);
+ ui->courseView->setCurrentIndex(ui->courseView->model()->index(0, NS_COURSE::NAME));
+ ui->courseView->setFixedWidth(ui->courseView->minimumSizeHint().width()
+ + ui->courseView->verticalScrollBar()->sizeHint().width()
+ + 7);
+
+ connect(ui->courseView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(adjustToCourse()));
+ //maintaining the foreign key's relations between tables
+ connect(ui->courseView->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(refresh()));
+ connect(RscMgr::modelHandler()->model(NS_TABLE::CLASS), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(refresh()));
+ connect(RscMgr::modelHandler()->model(NS_TABLE::STUDENT), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(refresh()));
+
+ adjustToCourse();
+}
+
+ResultWidget::~ResultWidget()
+{
+ delete ui;
+}
+
+void ResultWidget::adjustToCourse()
+{
+ m_resultProxyModel->setFilterRegExp(QString("^%1$").arg(ui->courseView->currentIndex().data().toString()));
+}
+
+void ResultWidget::refresh()
+{
+ RscMgr::modelHandler()->model(NS_TABLE::RESULT)->select();
+ adjustToCourse();
+}
+
+void ResultWidget::print()
+{
+ PrintOption opt;
+ opt.setColumnRemoved(NS_RESULT::ID, true);
+ opt.setColumnHidden(NS_RESULT::ID, true);
+ opt.setColumnHidden(NS_RESULT::COURSE, true);
+ opt.setMajorColumn(NS_RESULT::STUDENT);
+ opt.setColumnAggregative(NS_RESULT::COURSE, true);
+ opt.setColumnAggregative(NS_RESULT::STUDENT, true);
+ opt.setCurrentAggregativeColumn(NS_RESULT::COURSE);
+
+ PrintDialog dlg(m_resultProxyModel->sourceModel(), &opt);
+
+ dlg.exec();
+}
diff --git a/widgets/resultwidget.h b/widgets/resultwidget.h
new file mode 100644
index 0000000..1b5e06a
--- /dev/null
+++ b/widgets/resultwidget.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef RESULTWIDGET_H
+#define RESULTWIDGET_H
+
+#include
+
+class QSortFilterProxyModel;
+
+namespace Ui {
+class ResultWidget;
+}
+
+class ResultWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ResultWidget(QWidget *parent = 0);
+
+ ~ResultWidget();
+
+ void add();
+
+ void modify();
+
+ void remove();
+
+ void print();
+
+private slots:
+ void adjustToCourse();
+
+ void refresh();
+
+private:
+ Ui::ResultWidget *ui;
+
+ QSortFilterProxyModel *m_resultProxyModel;
+};
+
+#endif // RESULTWIDGET_H
diff --git a/widgets/settingwidget.cpp b/widgets/settingwidget.cpp
new file mode 100644
index 0000000..5be3f66
--- /dev/null
+++ b/widgets/settingwidget.cpp
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "settingwidget.h"
+#include "ui_settingwidget.h"
+
+#include "resourcemanager.h"
+#include "printoption.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+SettingWidget::SettingWidget(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::SettingWidget)
+{
+ ui->setupUi(this);
+
+ initialize();
+ createConnections();
+ loadSettings();
+
+ m_previewWidget->updatePreview();
+ m_previewWidget->setFixedWidth(m_previewWidget->sizeHint().width());
+
+ ui->settingListWidget->setCurrentRow(0);
+
+ ui->languageComboBox->insertItem(NS_Language::Arabic, tr("Arabic"));
+ ui->languageComboBox->insertItem(NS_Language::English, tr("English"));
+
+ // No need to indicate the current language in the combo box other than here,
+ // because SettingWidget is reconstructed upon each language change.
+ ui->languageComboBox->setCurrentIndex(RscMgr::settingHandler()->interfaceLanguage());
+
+ // To avoid infinite language change, we connect the "languageComboBox" here (after population).
+ connect(ui->languageComboBox, SIGNAL(currentIndexChanged(int)), SLOT(postLanguageChangeEvent(int)));
+}
+
+SettingWidget::~SettingWidget()
+{
+ delete ui;
+}
+
+bool SettingWidget::changeTheCurrentDatabase()
+{
+ QString newDatabasePath = QFileDialog::getOpenFileName(0, tr("Select a database"),
+ QDir::currentPath(),
+ "Furqan Database (*.fdb)");
+
+ if (newDatabasePath.isEmpty())
+ return false;
+
+ if (!RscMgr::databaseHandler()->ChangeCurrentDatabase(newDatabasePath)) {
+ RscMgr::issueMessage(tr("Program cannot use the selected database"), false);
+ return false;
+ }
+
+ RscMgr::issueMessage(tr("Database Changed"), true);
+
+ return true;
+}
+
+void SettingWidget::initialize()
+{
+ ui->headerImageFrame->hide();
+
+ m_previewWidget = new QPrintPreviewWidget(RscMgr::printHandler()->settingPreviewPrinter());
+ m_previewWidget->fitToWidth();
+
+ ui->previewFrame->layout()->addWidget(m_previewWidget);
+ ui->previewFrame->setMinimumWidth(500);
+
+ foreach (const QString printerName, QPrinterInfo::availablePrinterNames())
+ ui->printerComboBox->addItem(printerName);
+
+ m_pageSizeGroup = new QButtonGroup(this);
+ m_pageSizeGroup->addButton(ui->a4RadioButton, QPrinter::A4);
+ m_pageSizeGroup->addButton(ui->a5RadioButton, QPrinter::A5);
+
+ m_orientationGroup = new QButtonGroup(this);
+ m_orientationGroup->addButton(ui->portraitRadioButton, QPrinter::Portrait);
+ m_orientationGroup->addButton(ui->landscapeRadioButton, QPrinter::Landscape);
+
+ m_colorGroup = new QButtonGroup(this);
+ m_colorGroup->addButton(ui->grayScaleRadioButton, QPrinter::GrayScale);
+ m_colorGroup->addButton(ui->colorRadioButton, QPrinter::Color);
+
+ m_headerTypeGroup = new QButtonGroup(this);
+ m_headerTypeGroup->addButton(ui->headerNoneRadioButton, NS_HeaderType::None);
+ m_headerTypeGroup->addButton(ui->headerImageRadioButton, NS_HeaderType::Image);
+
+ m_headerAlignmentGroup = new QButtonGroup(this);
+ m_headerAlignmentGroup->addButton(ui->headerAlignLeftButton, Qt::AlignLeft);
+ m_headerAlignmentGroup->addButton(ui->headerAlignCenterButton, Qt::AlignHCenter);
+ m_headerAlignmentGroup->addButton(ui->headerAlignRightButton, Qt::AlignRight);
+}
+
+void SettingWidget::createConnections() const
+{
+ connect(ui->printerComboBox, SIGNAL(currentIndexChanged(QString)), RscMgr::settingHandler(), SLOT(setPrinterName(QString)));
+ connect(m_previewWidget, SIGNAL(paintRequested(QPrinter*)), SLOT(print(QPrinter*)));
+
+ connect(RscMgr::databaseHandler(), SIGNAL(currentDatabaseChanged(QString)), RscMgr::settingHandler(), SLOT(setDatabasePath(QString)));
+ connect(RscMgr::databaseHandler(), SIGNAL(currentDatabaseChanged(QString)), ui->dbPathLabel, SLOT(setText(QString)));
+
+ connect(m_pageSizeGroup, SIGNAL(buttonClicked(int)), RscMgr::settingHandler(), SLOT(setPrinterPageSize(int)));
+ connect(m_orientationGroup, SIGNAL(buttonClicked(int)), RscMgr::settingHandler(), SLOT(setPrinterOrientation(int)));
+ connect(m_colorGroup, SIGNAL(buttonClicked(int)), RscMgr::settingHandler(), SLOT(setPrinterColorMode(int)));
+ connect(m_headerTypeGroup, SIGNAL(buttonClicked(int)), RscMgr::settingHandler(), SLOT(setHeaderType(int)));
+ connect(m_headerAlignmentGroup, SIGNAL(buttonClicked(int)), RscMgr::settingHandler(), SLOT(setHeaderAlignment(int)));
+
+ connect(ui->leftSpinBox, SIGNAL(valueChanged(int)), RscMgr::settingHandler(), SLOT(setPrinterLeftMargin(int)));
+ connect(ui->topSpinBox, SIGNAL(valueChanged(int)), RscMgr::settingHandler(), SLOT(setPrinterTopMargin(int)));
+ connect(ui->rightSpinBox, SIGNAL(valueChanged(int)), RscMgr::settingHandler(), SLOT(setPrinterRightMargin(int)));
+ connect(ui->bottomSpinBox, SIGNAL(valueChanged(int)), RscMgr::settingHandler(), SLOT(setPrinterBottomMargin(int)));
+
+ connect(ui->headerWidthSpinBox, SIGNAL(valueChanged(int)), RscMgr::settingHandler(), SLOT(setHeaderWidthMM(int)));
+ connect(ui->headerHeightSpinBox, SIGNAL(valueChanged(int)), RscMgr::settingHandler(), SLOT(setHeaderHeightMM(int)));
+
+ connect(RscMgr::settingHandler(), SIGNAL(settingChanged()), SLOT(loadSettings()));
+ connect(RscMgr::settingHandler(), SIGNAL(settingChanged()), m_previewWidget, SLOT(updatePreview()));
+}
+
+void SettingWidget::on_headerImageButton_clicked()
+{
+ QString imagePath = QFileDialog::getOpenFileName(this,
+ QString(),
+ QDir::currentPath(),
+ "Image Files (*.png *.jpg *.jpeg *.bmp)");
+ if (!imagePath.isEmpty()) {
+ imagePath = QDir::toNativeSeparators(imagePath);
+ ui->headerImagePathLabel->setText(imagePath);
+ RscMgr::settingHandler()->setHeaderImagePath(imagePath);
+ }
+}
+
+void SettingWidget::loadSettings()
+{
+ ui->printerComboBox->setCurrentText(RscMgr::settingHandler()->printerName());
+ ui->dbPathLabel->setText(RscMgr::settingHandler()->databasePath());
+
+ m_pageSizeGroup->button(RscMgr::settingHandler()->printerPageSize())->setChecked(true);
+ m_orientationGroup->button(RscMgr::settingHandler()->printerOrientation())->setChecked(true);
+ m_colorGroup->button(RscMgr::settingHandler()->printerColorMode())->setChecked(true);
+ m_headerTypeGroup->button(RscMgr::settingHandler()->headerType())->setChecked(true);
+ m_headerAlignmentGroup->button(RscMgr::settingHandler()->headerAlignment())->setChecked(true);
+
+ ui->leftSpinBox->setValue(RscMgr::settingHandler()->printerLeftMargin());
+ ui->topSpinBox->setValue(RscMgr::settingHandler()->printerTopMargin());
+ ui->rightSpinBox->setValue(RscMgr::settingHandler()->printerRightMargin());
+ ui->bottomSpinBox->setValue(RscMgr::settingHandler()->printerBottomMargin());
+
+ ui->headerWidthSpinBox->setValue(RscMgr::settingHandler()->headerWidthMM());
+ ui->headerHeightSpinBox->setValue(RscMgr::settingHandler()->headerHeightMM());
+
+ ui->headerImagePathLabel->setText(RscMgr::settingHandler()->headerImagePath());
+}
+
+void SettingWidget::postLanguageChangeEvent(int lang) const
+{
+ if (lang < 0 || lang > NS_Language::English || lang == RscMgr::settingHandler()->interfaceLanguage())
+ return;
+
+ // Beacause subsequent operations depend on the settingHandler's new language,
+ // we set the new language here.
+ RscMgr::settingHandler()->setInterfaceLanguage(lang);
+
+ RscMgr::translatorHandler()->translate(static_cast(lang));
+
+ // Post a language change to re-initialize the main widget.
+ qApp->postEvent(qApp, new QEvent(QEvent::LanguageChange));
+}
+
+void SettingWidget::updatePreview() const
+{
+ m_previewWidget->updatePreview();
+}
+
+void SettingWidget::print(QPrinter *printer)
+{
+ PrintOption opt;
+ RscMgr::printHandler()->print(RscMgr::modelHandler()->previewModel(), &opt, printer);
+}
+
+QString SettingWidget::getPathToSave(const QString &text)
+{
+ QString path = QFileDialog::getSaveFileName(this, text,
+ QDir::currentPath(),
+ "Furqan Database (*.fdb)",
+ 0,
+ QFileDialog::DontConfirmOverwrite);
+
+ if (QFile(path).exists()) {
+ RscMgr::issueMessage(tr("A database with the same name exists !"), false);
+ return QString();
+ }
+
+ if (!path.isEmpty() && !path.endsWith(".fdb", Qt::CaseInsensitive))
+ path.append(".fdb");
+
+ return path;
+}
+
+void SettingWidget::on_backupDBButton_clicked()
+{
+ const QString &path = getPathToSave(tr("Select where to save the back up"));
+ if (path.isEmpty())
+ return;
+
+ if (!RscMgr::databaseHandler()->backupCurrentDatabase(path)) {
+ RscMgr::issueMessage(tr("Process cannot complete, an error occured"), false);
+ return;
+ }
+
+ RscMgr::issueMessage(tr("Backup Created"), true);
+}
+
+void SettingWidget::on_changeDBButton_clicked()
+{
+ changeTheCurrentDatabase();
+}
+
+void SettingWidget::on_zoomOutButton_clicked()
+{
+ m_previewWidget->zoomOut();
+}
+
+void SettingWidget::on_zoomInButton_clicked()
+{
+ m_previewWidget->zoomIn();
+}
+
+void SettingWidget::on_createDBButton_clicked()
+{
+ const QString &path = getPathToSave(tr("Select where to save the new database"));
+ if (path.isEmpty())
+ return;
+
+ if (!RscMgr::databaseHandler()->createNewDatabase(path)) {
+ RscMgr::issueMessage(tr("Process cannot complete, an error occured"), false);
+ return;
+ }
+
+ RscMgr::issueMessage(tr("Database Created"), true);
+}
diff --git a/widgets/settingwidget.h b/widgets/settingwidget.h
new file mode 100644
index 0000000..4fb56f4
--- /dev/null
+++ b/widgets/settingwidget.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef SETTINGWIDGET_H
+#define SETTINGWIDGET_H
+
+#include
+
+class QButtonGroup;
+class QPrintPreviewWidget;
+class QPrinter;
+
+namespace Ui {
+class SettingWidget;
+}
+
+class SettingWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit SettingWidget(QWidget *parent = 0);
+ ~SettingWidget();
+
+ static bool changeTheCurrentDatabase();
+
+ void updatePreview() const;
+
+private slots:
+ void on_headerImageButton_clicked();
+ void on_createDBButton_clicked();
+ void on_backupDBButton_clicked();
+ void on_changeDBButton_clicked();
+ void on_zoomOutButton_clicked();
+ void on_zoomInButton_clicked();
+
+ void print(QPrinter *printer);
+
+ QString getPathToSave(const QString &text);
+
+ void loadSettings();
+
+ void postLanguageChangeEvent(int) const;
+
+private:
+ void initialize();
+
+ void createConnections() const;
+
+ Ui::SettingWidget *ui;
+
+ QPrintPreviewWidget *m_previewWidget;
+
+ QButtonGroup *m_pageSizeGroup;
+ QButtonGroup *m_orientationGroup;
+ QButtonGroup *m_colorGroup;
+ QButtonGroup *m_headerTypeGroup;
+ QButtonGroup *m_headerAlignmentGroup;
+};
+
+#endif // SETTINGWIDGET_H
diff --git a/widgets/studentwidget.cpp b/widgets/studentwidget.cpp
new file mode 100644
index 0000000..5d0c7cd
--- /dev/null
+++ b/widgets/studentwidget.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "studentwidget.h"
+#include "ui_studentwidget.h"
+
+#include "resourcemanager.h"
+#include "uniquedelegate.h"
+#include "datedelegate.h"
+#include "sqldelegate.h"
+#include "mapdelegate.h"
+#include "printdialog.h"
+#include "printoption.h"
+
+#include
+#include
+
+StudentWidget::StudentWidget(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::StudentWidget)
+{
+ ui->setupUi(this);
+
+ m_studentProxyModel = new QSortFilterProxyModel(this);
+ m_studentProxyModel->setSourceModel(RscMgr::modelHandler()->model(NS_TABLE::STUDENT));
+ m_studentProxyModel->setFilterKeyColumn(NS_STUDENT::CLASS);
+
+ ui->studentView->setModel(m_studentProxyModel);
+ ui->studentView->hideColumn(NS_STUDENT::ID);
+ ui->studentView->hideColumn(NS_STUDENT::CLASS);
+ ui->studentView->setItemDelegateForColumn(NS_STUDENT::FULL_NAME, new UniqueDelegate(ui->studentView));
+ ui->studentView->setItemDelegateForColumn(NS_STUDENT::FATHER_NAME, new UniqueDelegate(ui->studentView));
+ ui->studentView->setItemDelegateForColumn(NS_STUDENT::GENDER, new MapDelegate(ui->studentView));
+ ui->studentView->setItemDelegateForColumn(NS_STUDENT::LEVEL, new MapDelegate(ui->studentView));
+ ui->studentView->setItemDelegateForColumn(NS_STUDENT::BIRTH_DATE, new DateDelegate(ui->studentView));
+ ui->studentView->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents);
+ ui->studentView->horizontalHeader()->setSectionResizeMode(NS_STUDENT::FULL_NAME, QHeaderView::Stretch);
+
+ ui->classView->setModel(RscMgr::modelHandler()->model(NS_TABLE::CLASS));
+ ui->classView->setModelColumn(NS_CLASS::NAME);
+ ui->classView->setCurrentIndex(ui->classView->model()->index(0, NS_CLASS::NAME));
+ ui->classView->setFixedWidth(ui->classView->minimumSizeHint().width()
+ + ui->classView->verticalScrollBar()->sizeHint().width()
+ + 7);
+
+ connect(ui->classView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(adjustToClass()));
+ //maintaining the foreign key's relations between tables
+ connect(ui->classView->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(refresh()));
+
+ adjustToClass();
+}
+
+StudentWidget::~StudentWidget()
+{
+ delete ui;
+}
+
+void StudentWidget::adjustToClass()
+{
+ m_studentProxyModel->setFilterRegExp(QString("^%1$").arg(ui->classView->currentIndex().data().toString()));
+}
+
+void StudentWidget::refresh()
+{
+ RscMgr::modelHandler()->model(NS_TABLE::STUDENT)->select();
+ adjustToClass();
+}
+
+void StudentWidget::add()
+{
+ if (!ui->classView->currentIndex().isValid()) {
+ RscMgr::issueMessage(tr("Please select a class first."), false);
+ return;
+ }
+
+ QMap map;
+ map.insert(NS_STUDENT::CLASS,
+ ui->classView->currentIndex()
+ .sibling(ui->classView->currentIndex().row(), NS_CLASS::ID).data());
+
+ RscMgr::modelHandler()->insertRow(NS_TABLE::STUDENT, map);
+
+ const QModelIndex &idx = ui->studentView->model()->index(0, NS_STUDENT::FULL_NAME);
+
+ ui->studentView->setCurrentIndex(idx);
+ ui->studentView->edit(idx);
+}
+
+void StudentWidget::modify()
+{
+ if (!ui->studentView->currentIndex().isValid())
+ return;
+
+ ui->studentView->edit(ui->studentView->currentIndex());
+}
+
+void StudentWidget::remove()
+{
+ if (!ui->studentView->currentIndex().isValid())
+ return;
+
+ RscMgr::modelHandler()->removeRow(NS_TABLE::STUDENT, ui->studentView->currentIndex().row());
+
+ ui->studentView->setFocus();
+ ui->studentView->setCurrentIndex(ui->studentView->model()->index(0, NS_STUDENT::FULL_NAME));
+}
+
+void StudentWidget::print()
+{
+ PrintOption opt;
+ opt.setColumnRemoved(NS_STUDENT::ID, true);
+ opt.setColumnHidden(NS_STUDENT::ID, true);
+ opt.setColumnHidden(NS_STUDENT::CLASS, true);
+ opt.setMajorColumn(NS_STUDENT::FULL_NAME);
+ opt.setColumnAggregative(NS_STUDENT::LEVEL, true);
+ opt.setColumnAggregative(NS_STUDENT::CLASS, true);
+ opt.setCurrentAggregativeColumn(NS_STUDENT::CLASS);
+
+ PrintDialog dlg(m_studentProxyModel->sourceModel(), &opt);
+
+ dlg.exec();
+}
diff --git a/widgets/studentwidget.h b/widgets/studentwidget.h
new file mode 100644
index 0000000..4961ab1
--- /dev/null
+++ b/widgets/studentwidget.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef STUDENTWIDGET_H
+#define STUDENTWIDGET_H
+
+#include
+
+class QSortFilterProxyModel;
+
+namespace Ui {
+class StudentWidget;
+}
+
+class StudentWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit StudentWidget(QWidget *parent = 0);
+
+ ~StudentWidget();
+
+ void add();
+
+ void modify();
+
+ void remove();
+
+ void print();
+
+private slots:
+ void adjustToClass();
+
+ void refresh();
+
+private:
+ Ui::StudentWidget *ui;
+
+ QSortFilterProxyModel *m_studentProxyModel;
+};
+
+#endif // STUDENTWIDGET_H
diff --git a/widgets/teacherwidget.cpp b/widgets/teacherwidget.cpp
new file mode 100644
index 0000000..97d4a9b
--- /dev/null
+++ b/widgets/teacherwidget.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "teacherwidget.h"
+#include "ui_teacherwidget.h"
+
+#include "resourcemanager.h"
+#include "uniquedelegate.h"
+#include "mapdelegate.h"
+#include "datedelegate.h"
+#include "printdialog.h"
+#include "printOption.h"
+
+TeacherWidget::TeacherWidget(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::TeacherWidget)
+{
+ ui->setupUi(this);
+
+ ui->teacherView->setModel(RscMgr::modelHandler()->model(NS_TABLE::TEACHER));
+ ui->teacherView->hideColumn(NS_TEACHER::ID);
+ ui->teacherView->setItemDelegateForColumn(NS_TEACHER::FULL_NAME, new UniqueDelegate(ui->teacherView));
+ ui->teacherView->setItemDelegateForColumn(NS_TEACHER::FATHER_NAME, new UniqueDelegate(ui->teacherView));
+ ui->teacherView->setItemDelegateForColumn(NS_TEACHER::GENDER, new MapDelegate(ui->teacherView));
+ ui->teacherView->setItemDelegateForColumn(NS_TEACHER::BIRTH_DATE, new DateDelegate(ui->teacherView));
+ ui->teacherView->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents);
+ ui->teacherView->horizontalHeader()->setSectionResizeMode(NS_TEACHER::FULL_NAME, QHeaderView::Stretch);
+ ui->teacherView->setCurrentIndex(ui->teacherView->model()->index(0, NS_TEACHER::FULL_NAME));
+}
+
+TeacherWidget::~TeacherWidget()
+{
+ delete ui;
+}
+
+void TeacherWidget::add()
+{
+ RscMgr::modelHandler()->insertRow(NS_TABLE::TEACHER);
+
+ const QModelIndex &idx = ui->teacherView->model()->index(0, NS_TEACHER::FULL_NAME);
+
+ ui->teacherView->setCurrentIndex(idx);
+ ui->teacherView->edit(idx);
+}
+
+void TeacherWidget::modify()
+{
+ if (!ui->teacherView->currentIndex().isValid())
+ return;
+
+ ui->teacherView->edit(ui->teacherView->currentIndex());
+}
+
+void TeacherWidget::remove()
+{
+ if (!ui->teacherView->currentIndex().isValid())
+ return;
+
+ RscMgr::modelHandler()->removeRow(NS_TABLE::TEACHER, ui->teacherView->currentIndex().row());
+
+ ui->teacherView->setFocus();
+ ui->teacherView->setCurrentIndex(ui->teacherView->model()->index(0, NS_TEACHER::FATHER_NAME));
+}
+
+void TeacherWidget::print()
+{
+ PrintOption opt;
+ opt.setColumnRemoved(NS_TEACHER::ID, true);
+ opt.setColumnHidden(NS_TEACHER::ID, true);
+ opt.setMajorColumn(NS_TEACHER::FULL_NAME);
+ opt.setColumnAggregative(NS_TEACHER::GENDER, true);
+ opt.setColumnAggregative(NS_TEACHER::NATIONALITY, true);
+ opt.setColumnAggregative(NS_TEACHER::RESIDENCY, true);
+
+ PrintDialog dlg(ui->teacherView->model(), &opt);
+ dlg.exec();
+}
diff --git a/widgets/teacherwidget.h b/widgets/teacherwidget.h
new file mode 100644
index 0000000..9606820
--- /dev/null
+++ b/widgets/teacherwidget.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef TEACHERWIDGET_H
+#define TEACHERWIDGET_H
+
+#include
+
+namespace Ui {
+class TeacherWidget;
+}
+
+class TeacherWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit TeacherWidget(QWidget *parent = 0);
+
+ ~TeacherWidget();
+
+ void add();
+
+ void modify();
+
+ void remove();
+
+ void print();
+
+private:
+ Ui::TeacherWidget *ui;
+};
+
+#endif // TEACHERWIDGET_H
diff --git a/widgets/teachingwidget.cpp b/widgets/teachingwidget.cpp
new file mode 100644
index 0000000..e7c1197
--- /dev/null
+++ b/widgets/teachingwidget.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "teachingwidget.h"
+#include "ui_teachingwidget.h"
+
+#include "resourcemanager.h"
+#include "sqldelegate.h"
+#include "printdialog.h"
+#include "printoption.h"
+
+#include
+#include
+
+TeachingWidget::TeachingWidget(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::TeachingWidget)
+{
+ ui->setupUi(this);
+
+ m_teachingProxyModel = new QSortFilterProxyModel(this);
+ m_teachingProxyModel->setSourceModel(RscMgr::modelHandler()->model(NS_TABLE::TEACHING));
+ m_teachingProxyModel->setFilterKeyColumn(NS_TEACHING::TEACHER);
+
+ ui->teachingView->setModel(m_teachingProxyModel);
+ ui->teachingView->hideColumn(NS_TEACHING::ID);
+ ui->teachingView->hideColumn(NS_TEACHING::TEACHER);
+ ui->teachingView->setItemDelegateForColumn(NS_TEACHING::TEACHER, new SqlDelegate(true, ui->teachingView));
+ ui->teachingView->setItemDelegateForColumn(NS_TEACHING::CLASS, new SqlDelegate(true, ui->teachingView));
+ ui->teachingView->setItemDelegateForColumn(NS_TEACHING::COURSE, new SqlDelegate(true, ui->teachingView));
+ ui->teachingView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+
+ ui->teacherView->setModel(RscMgr::modelHandler()->model(NS_TABLE::TEACHER));
+ ui->teacherView->setModelColumn(NS_TEACHER::FULL_NAME);
+ ui->teacherView->setCurrentIndex(ui->teacherView->model()->index(0, NS_TEACHER::FULL_NAME));
+ ui->teacherView->setFixedWidth(ui->teacherView->minimumSizeHint().width()
+ + ui->teacherView->verticalScrollBar()->sizeHint().width()
+ + 7);
+
+ connect(ui->teacherView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(adjustToTeacher()));
+ //maintaining the foreign key's relations between tables
+ connect(ui->teacherView->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(refresh()));
+ connect(RscMgr::modelHandler()->model(NS_TABLE::CLASS), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(refresh()));
+ connect(RscMgr::modelHandler()->model(NS_TABLE::COURSE), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(refresh()));
+
+ adjustToTeacher();
+}
+
+TeachingWidget::~TeachingWidget()
+{
+ delete ui;
+}
+
+void TeachingWidget::adjustToTeacher()
+{
+ m_teachingProxyModel->setFilterRegExp(QString("^%1$").arg(ui->teacherView->currentIndex().data().toString()));
+}
+
+void TeachingWidget::refresh()
+{
+ RscMgr::modelHandler()->model(NS_TABLE::TEACHING)->select();
+ adjustToTeacher();
+}
+
+void TeachingWidget::add()
+{
+ if (!ui->teacherView->currentIndex().isValid()) {
+ RscMgr::issueMessage(tr("Please select a teacher first."), false);
+ return;
+ }
+
+ QMap map;
+ map.insert(NS_TEACHING::TEACHER,
+ ui->teacherView->currentIndex()
+ .sibling(ui->teacherView->currentIndex().row(), NS_TEACHER::ID).data());
+
+ RscMgr::modelHandler()->insertRow(NS_TABLE::TEACHING, map);
+
+ const QModelIndex &idx = ui->teachingView->model()->index(0, NS_TEACHING::CLASS);
+
+ ui->teachingView->setCurrentIndex(idx);
+ ui->teachingView->edit(idx);
+}
+
+void TeachingWidget::modify()
+{
+ if (!ui->teachingView->currentIndex().isValid())
+ return;
+
+ ui->teachingView->edit(ui->teachingView->currentIndex());
+}
+
+void TeachingWidget::remove()
+{
+ if (!ui->teachingView->currentIndex().isValid())
+ return;
+
+ RscMgr::modelHandler()->removeRow(NS_TABLE::TEACHING, ui->teachingView->currentIndex().row());
+
+ ui->teachingView->setFocus();
+ ui->teachingView->setCurrentIndex(ui->teachingView->model()->index(0, NS_TEACHING::CLASS));
+}
+
+void TeachingWidget::print()
+{
+ PrintOption opt;
+
+ opt.setColumnRemoved(NS_TEACHING::ID, true);
+ opt.setColumnHidden(NS_TEACHING::ID, true);
+ opt.setMajorColumn(-1);
+ opt.setColumnAggregative(NS_TEACHING::TEACHER, true);
+ opt.setColumnAggregative(NS_TEACHING::CLASS, true);
+ opt.setColumnAggregative(NS_TEACHING::COURSE, true);
+
+ opt.setCurrentAggregativeColumn(NS_TEACHING::TEACHER);
+
+ PrintDialog dlg(m_teachingProxyModel->sourceModel(), &opt);
+
+ dlg.exec();
+}
diff --git a/widgets/teachingwidget.h b/widgets/teachingwidget.h
new file mode 100644
index 0000000..b5f6133
--- /dev/null
+++ b/widgets/teachingwidget.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef TEACHINGWIDGET_H
+#define TEACHINGWIDGET_H
+
+#include
+
+class QSortFilterProxyModel;
+
+namespace Ui {
+class TeachingWidget;
+}
+
+class TeachingWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit TeachingWidget(QWidget *parent = 0);
+
+ ~TeachingWidget();
+
+ void add();
+
+ void modify();
+
+ void remove();
+
+ void print();
+
+private slots:
+ void adjustToTeacher();
+
+ void refresh();
+
+private:
+ Ui::TeachingWidget *ui;
+
+ QSortFilterProxyModel *m_teachingProxyModel;
+};
+
+#endif // TEACHINGWIDGET_H
diff --git a/widgets/texteditor.cpp b/widgets/texteditor.cpp
new file mode 100644
index 0000000..713debe
--- /dev/null
+++ b/widgets/texteditor.cpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "texteditor.h"
+
+#include "resourcemanager.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+TextEditor::TextEditor(QWidget *parent)
+ : QWidget(parent), m_colorDialog(0)
+{
+ createWidgets();
+ createLayout();
+ createConnections();
+
+ updateColorSwatch();
+
+ m_textEdit->setFocus();
+}
+
+void TextEditor::createWidgets()
+{
+ QFont font("Arial", 14);
+
+ m_textEdit = new QTextEdit;
+ m_textEdit->setAcceptRichText(true);
+ m_textEdit->setAlignment(RscMgr::dir() == Qt::LeftToRight ? Qt::AlignLeft : Qt::AlignRight);
+ m_textEdit->setTabChangesFocus(true);
+ m_textEdit->setCurrentFont(font);
+
+ m_fontToolBar = new QToolBar;
+ m_fontToolBar->setIconSize(QSize(20, 20));
+
+ m_fontFamilyCombo = new QFontComboBox;
+ m_fontFamilyCombo->setCurrentFont(font);
+
+ m_fontToolBar->addWidget(m_fontFamilyCombo);
+
+ m_fontSizeSpin = new QDoubleSpinBox;
+ m_fontSizeSpin->setFixedHeight(20);
+ m_fontSizeSpin->setDecimals(0);
+ m_fontSizeSpin->setRange(6, 280);
+ m_fontSizeSpin->setValue(font.pointSize());
+
+ m_fontToolBar->addWidget(m_fontSizeSpin);
+
+ m_boldAction = m_fontToolBar->addAction(QIcon(":/bold"), tr("Bold"));
+ m_boldAction->setCheckable(true);
+ m_boldAction->setShortcut(tr("Ctrl+B"));
+
+ m_italicAction = m_fontToolBar->addAction(QIcon(":/italic"), tr("Italic"));
+ m_italicAction->setCheckable(true);
+ m_italicAction->setShortcut(tr("Ctrl+I"));
+
+ m_underlineAction = m_fontToolBar->addAction(QIcon(":/underline"), tr("Underline"));
+ m_underlineAction->setCheckable(true);
+ m_underlineAction->setShortcut(tr("Ctrl+U"));
+
+ m_colorAction = m_fontToolBar->addAction(tr("Color"));
+}
+
+void TextEditor::createLayout()
+{
+ QHBoxLayout *toolbarLayout = new QHBoxLayout;
+ toolbarLayout->setContentsMargins(2, 2, 2, 2);
+ toolbarLayout->addWidget(m_fontToolBar);
+
+ QFrame *frame = new QFrame;
+ frame->setFrameShape(QFrame::StyledPanel);
+ frame->setFrameShadow(QFrame::Raised);
+ frame->setLayout(toolbarLayout);
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->setSpacing(3);
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->addWidget(frame);
+ layout->addWidget(m_textEdit);
+ setLayout(layout);
+}
+
+void TextEditor::createConnections()
+{
+ connect(m_fontFamilyCombo, SIGNAL(currentFontChanged(const QFont&)),
+ this, SLOT(setFontFamily(const QFont&)));
+ connect(m_fontSizeSpin, SIGNAL(valueChanged(double)),
+ this, SLOT(setFontPointSize(double)));
+ connect(m_boldAction, SIGNAL(toggled(bool)),
+ this, SLOT(setBold(bool)));
+ connect(m_italicAction, SIGNAL(toggled(bool)),
+ m_textEdit, SLOT(setFontItalic(bool)));
+ connect(m_underlineAction, SIGNAL(toggled(bool)),
+ m_textEdit, SLOT(setFontUnderline(bool)));
+ connect(m_colorAction, SIGNAL(triggered()),
+ this, SLOT(setColor()));
+ connect(m_textEdit, SIGNAL(currentCharFormatChanged(const QTextCharFormat&)),
+ this, SLOT(currentCharFormatChanged(const QTextCharFormat&)));
+ connect(m_textEdit, SIGNAL(textChanged()),
+ this, SIGNAL(textChanged()));
+}
+
+void TextEditor::currentCharFormatChanged(const QTextCharFormat &format)
+{
+ m_fontFamilyCombo->setCurrentFont(format.font());
+ m_fontSizeSpin->setValue(format.fontPointSize());
+ m_boldAction->setChecked(format.fontWeight() == QFont::Bold);
+ m_italicAction->setChecked(format.fontItalic());
+ m_underlineAction->setChecked(format.fontUnderline());
+
+ updateColorSwatch();
+}
+
+void TextEditor::setColor()
+{
+ if (!m_colorDialog) {
+ m_colorDialog = new QColorDialog(this);
+ connect(m_colorDialog, SIGNAL(colorSelected(const QColor&)),
+ this, SLOT(updateColor(const QColor&)));
+ }
+ m_colorDialog->setCurrentColor(m_textEdit->textColor());
+ m_colorDialog->open();
+}
+
+void TextEditor::updateColor(const QColor &color)
+{
+ m_textEdit->setTextColor(color);
+ updateColorSwatch();
+ emit fontColorChanged(color.name(QColor::HexRgb));
+}
+
+void TextEditor::updateColorSwatch()
+{
+ QPixmap colorSwatch(32, 32);
+ colorSwatch.fill(m_textEdit->textColor());
+ m_colorAction->setIcon(QIcon(colorSwatch));
+}
diff --git a/widgets/texteditor.h b/widgets/texteditor.h
new file mode 100644
index 0000000..43ec55d
--- /dev/null
+++ b/widgets/texteditor.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 30-8-2016 Abdullateef Qallaa
+ *
+ * This file is part of Furqan project,
+ * hosted on GitHub: https://github.com/laateef/furqan,
+ * licensed under GPLv3.
+ *
+ * GNU General Public License Usage
+ * This file may be used under the terms of the GNU
+ * General Public License version 3.0 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.md included in the
+ * packaging of this file. Please review the following information to
+ * ensure the GNU General Public License version 3.0 requirements will be
+ * met: http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifndef TEXTEDITOR_H
+#define TEXTEDITOR_H
+
+#include
+#include
+
+class QColorDialog;
+class QDoubleSpinBox;
+class QFontComboBox;
+class QTextCharFormat;
+class QToolBar;
+
+class TextEditor : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit TextEditor(QWidget *parent=0);
+
+ QString toHtml() const { return m_textEdit->toHtml(); }
+ QString toPlainText() const { return m_textEdit->toPlainText(); }
+ QTextDocument *document() const { return m_textEdit->document(); }
+
+ void setFontFamily(const QString &family) { m_textEdit->setFontFamily(family); }
+
+ void setFontSize(const QString &size) { m_textEdit->setFontPointSize(size.toInt()); }
+
+ void setFontColor(const QString &color) {
+ m_textEdit->setTextColor(QColor(color));
+ updateColorSwatch();
+ }
+
+signals:
+ void textChanged();
+
+ void fontFamilyChanged(const QString &fontFamily) const;
+ void fontSizeChanged(const QString &fontSize) const;
+ void fontColorChanged(const QString &fontColor) const;
+
+public slots:
+ void setHtml(const QString &html) { m_textEdit->setHtml(html); }
+
+private slots:
+ void setBold(bool on) { m_textEdit->setFontWeight(on ? QFont::Bold : QFont::Normal); }
+
+ void setColor();
+
+ void updateColor(const QColor &color);
+
+ void setFontPointSize(double points) {
+ m_textEdit->setFontPointSize(static_cast(points));
+ emit fontSizeChanged(QString::number(points));
+ }
+
+ void setFontFamily(const QFont &font) {
+ m_textEdit->setFontFamily(font.family());
+ emit fontFamilyChanged(font.family());
+ }
+
+ void currentCharFormatChanged(const QTextCharFormat &format);
+
+private:
+ void createWidgets();
+ void createLayout();
+ void createConnections();
+ void updateColorSwatch();
+
+ QToolBar *m_fontToolBar;
+
+ QAction *m_boldAction;
+ QAction *m_italicAction;
+ QAction *m_underlineAction;
+ QAction *m_colorAction;
+
+ QColorDialog *m_colorDialog;
+
+ QFontComboBox *m_fontFamilyCombo;
+
+ QDoubleSpinBox *m_fontSizeSpin;
+
+ QTextEdit *m_textEdit;
+};
+
+#endif // TEXTEDITOR_H