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