diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/COPYING @@ -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. + + + Copyright (C) + + 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: + + Copyright (C) + 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 index a48c426..1227378 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # LimeReport ##How to use it -* Build limereport.pro. It will create a limereport shared library -* In your project connect the limereport library then in source code add: +1. Build limereport.pro. It will create a limereport shared library +2. In your project connect the limereport library then in source code add: ```C #include "lrreportengine.h" to add report engine @@ -15,4 +15,4 @@ report->printReport(); to print report ``` -For more samples see a demo\r1 \ No newline at end of file +For more samples see a demo \ No newline at end of file diff --git a/demo/r1/demo_reports/categories.lrxml b/demo/r1/demo_reports/categories.lrxml new file mode 100644 index 0000000..165a91e --- /dev/null +++ b/demo/r1/demo_reports/categories.lrxml @@ -0,0 +1,170 @@ + + + + + + page1 + + + + + + + + ReportPage1 + + + + DataBand1 + + + + ImageItem1 + + + + + DataBand1 + + + + + + category + Picture + + + + + + ReportPage1 + + + + + + + category + + + + + + + SubDetailBand1 + + + + TextItem1 + + + + + SubDetailBand1 + + + $D{products.ProductName} + + + + + + + + + + + + + + + TextItem2 + + + + + SubDetailBand1 + + + $D{products.UnitPrice} + + + + + + + + + + + + + + + + + ReportPage1 + + + + DataBand1 + + + products + + + + + + + + + + + + + + + + + datasources + + + + northwind + QSQLITE + ./demo_reports/northwind.db + + + + + + + + + + category + Select * from categories + northwind + + + + + + products + Select * from products where CategoryID = $D{category.CategoryID} + northwind + category + + + + + + + TestName + TestValue + + + + + diff --git a/demo/r1/demo_reports/demoReport1_report_header_group_subdetail.lrxml b/demo/r1/demo_reports/demoReport1_report_header_group_subdetail.lrxml new file mode 100644 index 0000000..e036b0e --- /dev/null +++ b/demo/r1/demo_reports/demoReport1_report_header_group_subdetail.lrxml @@ -0,0 +1,632 @@ + + + + + + page1 + + + + + + + + ReportPage1 + + + + ReportHeader1 + + + + TextItem1 + + + + + ReportHeader1 + + + Lime +Report + + + + + + + + + + + + + + + ImageItem1 + + + + + ReportHeader1 + + + 89504e470d0a1a0a0000000d494844520000006400000071080600000023f9067c000000097048597300000dd700000dd70142289b780000119c49444154789ced9d79701cd59dc73feff55cba46b7c18eed8d84c1b6c02c4636b58ea928d8c609b0bb64c3429104ca5420b001c292cd3ae50d7120091bbb300e570a0c2609391c0889b99c1828b0036c42488c8d8d1cf9968c25d91aeb1849a3397afa78fb47cf48e383b2248f3c9a91be5553d3d3afbbe7757ffbbddfeffd8ef704a780dfef07104208745d17a73a7e1c83871002c330304d13c00638e503deb871a36bf1e2c5771886e1374d5328a546ba9e630642086f2010f8d3b469d35ec7e1c2729deaa44020e002beee72b9ced6340da5d4782b49135c2e577e28145a0b6c077a80e82909e9eaea12b66d8b6834aaaf5cb9f2059fcf67bb5c2e4388715e868b4824622e58b060e6a5975eba2810084c00a602fb180421a2b7b7570098a669ad58b1621b70180802d688d63ab711abadadfdbc94b2ce344d17e00524c0295b4812524a05f402078056c0601032681c274001d1d9b367cf9152da899e46e13c4b31684212308128104e6c8f6378b04b4b4b63272b182a2149a894cf38860129e5c9f79fe17a8ce31418276494619c905186e1ca9013a094e2b8b1c9b806360c199b36428410ac59b3068fc7a3b5b5b5b9bababa4428143a9ea49c47d23ed5d8d8686fdebcd92461a31a2cd24608c0c2850b7d555555cb84105f554a598ccd56226ddb8eb6b4b43c595d5dfd108e5818f41021ad843cf0c003f1bababab57bf6ec79aba9a9a9c2300c4f3aaf9f0d104208cbb2ac8f3efa28004c04dac904215eaf97b56bd7aab56bd776242a509cb8fe586b25c9f1591c88e0989804839427692344d7f56465e240178ef5722c43e190613104e19e36426ebdf5569e7aeaa964454cc64d2b082150437420a58d90a79e7a0aa514efbfff3eab57af1e6bddd431b02c8bbd7bf7aa1d3b760cf9dcb40af59e9e1e317dfaf4090f3ffc70795f5f9fb42c6b4c12a394b21b1b1b3bafbcf2ca761cb5f7cc7759008140c05b5555f5359fcf779bdfef5763d1bb2884909665450dc3580bfc08a7eb36067b7eda0859b06001d3a74fd78195c033c0598087b1a76541c2e721a5acb46d3b309413d346c8e6cd9b939b16d08df356b8187b26faa48a6bd8b6ddc710959bb476590c6858a1c4672cb68e54d864ca7492625c5443ad44aec2e7f3118b9dd431f8b148ab71f1b5d75ea3a4a4c4130c06dddddddda2afaf6fccb590847151eddab5cb7cf4d147e389dd99d1b2ce39e79c7ee3a26ddb63dab8d8dadafae4a38f3efa50625f668c8bf7dd775fbcaeae6ecdae5dbbde3874e85085aeeb1e31d6ecef806ddb564b4b4b07703699322e161414b06edd3ab56eddba2e1c197214d0d275fd2c4252cbd2851091841b62d0481b21e1709844450c9c40ba1ec6669705098baf52ca66880185692364f7eeddcc98312359199381e0afb186fefbcecfcf27128964c6b83863c60c945284c361d78e1d3bdcb66dd3d1d131e644881002d33469686830972f5f9e941d99d1b2745d777b3c9e2f5e72c9255799a6698f455b168e96a55f78e1851b962f5fbe9e449ac1604f4e2b211b366c50b5b5b507dadbdbff1608048ae2f1b89b2178cb720022d1428cfafa7a1ba8648881e9692364e6cc995c7bedb516b0056804ca0177baae9f6550802ea554b66d674686ecdab52b591113c7853bd66d59966ddb0619362e82330689e3a8bf63a5ab3a1ec96e3a738172c761ac47c60ffbdec7637b4719c60919651895849c247226db9403c731348c14f2919221a7052104adadad1228080402aeaeae2e2984c80a992484108661a88686065d08116588f274541202e0f7fb27e4e7e7ff72c284093312ba7c56b49244d449a4babafac96f7ce31b8f3030141814462d21f7dd775fd7942953beb67dfbf6a99d9d9d2596656585295f08816559768a3fe428d94ec8d2a54b59b56a958993131f05f271e45d56b4129cb19821840867cc1f924eac5ab50a9c9b8ae1bc6182ec21230995202373093b23802185618e420cb9eea352edede93926934165eb2767d4dee2e26294526cd9b2456cd8b0411ac6a04363338e8450a7bebe5e2554f5cc587bd38d7038ecaea9a939b7aaaaaa3012896493fc10b66d5b4d4d4d6dafbefaea61ce60f4fb097fb264c9127efef39f9fc62507609a66797e7efe8352ca595eaf17b247a80bdbb663c160f027c0c33856ef918d7eafacaca4a1a1a1f0e8d1a3de482422a2d1a8d075ddb8fcf2cbfb18620ad7c9b06cd9324a4a4a8e02d700938032b22b705b0171b7db5d6e18c6d1a19c382c42962d5be6292d2d5d5b565676594272d9e170f843e0cb38898e3aa7f1f056ae5c090331c2dd89eb659b2bd8300c23c299705099a629955213344d3b0b48469b848099c01e1c07d5e93ebc64026932c62b9bc848be3c4356db874548381c3e7e324c158bc5bc38ddcb41d2d7df67f33450c3aaf3b0083959ac956ddb9263f3d2d3d9c5642321c3c2a81c188e658c1332ca907142dc19afc1e8c219893ab9f762b4da4a64811b615a1034503fdc86f56117b691620bfde3bfc0c2dfc3d042cb720be924a49f849716e3bdb01caf5be2366c8a8a3d7c420a2a04e4d90a6528621797d3da1aa1cd52e85183d89fdb885eb681380965604609ecee4e63edb204e9214408a46dca7228bc773ee72d9acc055e8d85122e9282a9273b65820fa6158361531f3579775a31af4d29e2fd8e183df7be4f647777d69bde8785d327c48c23224151d9f466d95faee1bfce2d67e6604f15804732cbe36156b187dbaafd341f8ef0649ec66fdf0d70f8a583843501961a3bc40c8b903e7c0acb8058103e781136de4f61a0a5e0dc0a669ecea3f348a67cb290fbefba80db3f33891fe8162fbfda4c72fead3141ca500951000b8ffcc6cf960945bcf1001cdae34ca0e1e1844766296c4b61db0a4b2994022500211002a426909ac475fc30d3ab31694e254f3c5dc7e2a5efb1fcd7fb69c4b167e57cfefb500991f75ccc9485d6f65bdcbfbc792e0a671af914580a3b6e61e8367a632f47767773784f0f6d2d7d043b6284f35c70561ebe73fd949d5fc6e4e9c55495fba870493c9a18a88f0026e5f36f3f9ecf3fe4bbb8f3e9ddd4e3182e739a945313229cf80261c5e51dd3a8f9ce6c7ee4d198e894258e51604b4df5e956744f0fcdcfede783c71bd819b368c3310c8670e68bd719485e71013ea0e8a6f39875fbf95c3eab8c4bbc927c2106c647255e2e5e71098fb784f9da6bcdd47b35a2ba95bba47c2c21791a442de8a140a18744c18edff91fa9e3db9a9692eaac004d424105ed65b37aae7a70d3b35b8334006d4000e8c021248663b94d9dfb2369fbf23eb397bf3fb397376e3a8fb9df9bc36d930b982585f33f0228f372e1e397f2fdea67f9ba6e71c82389c67394928f1d27479df7585dd3fc44a1f6c62abf6bdd1d9e63c800c82b82e90b50776f523d37fc2ab4354883807ae03d9c55630ee01013c46921111c726289ed10d029042dc0ee67f6f2d2dc17b9635b07eb554ad72405727201f35ff92cb70065713b7733b34e2024d5aa1eb811ff25a2f1dbf20f2bca8f6f4b76e104c5d5f7c3dd6fc0e40bd08c3e05f42868c621a10fa755243d8827d39214602b852520ecd1683f1ae5c36bdfe47b1f74f08bd403dd92fc4bcfe6ba697e2e000a4f56f75cc03137a5be95101940eb0d1496f9f88e4772776abbb015ea48dc133cfa8535dd2cb82b71627fe86dd27f3cd4d5779402e21696df4de4608803dfdfca836d11de4af5ace4bba87c643ed703a5621407689c0efa09e9b909c403cef681ebc99b90c77fba044b530fb614f6fe5e5a17bfee59d75531abfd24d74bfa4086eda0ea359c94b8973fe2c0abcdacb0ed810001af46de45657c0a98a29cf0d26c097c18342440e3f550fc8cb3a3fd465c530ab9c125b83ff54025a4aaefe4e0dc17f84553c4b3bdd45fd03782f55240ac3bcedfdb63fcb67faf80420f155f9ac66c72b4db9200d5cf393f1e9c8328f430df2d5973ec511a91c973f58b5fe0b95e83bf9f555eb2c3eff78747ba72af7c446720ca2bfd3b14b804de4f4fe47cc04f0ea65d1ff386dd7201555e8d678fd92f04d6d4b976f8a6e7a2ca11d6fb6a6a6a9add6ef7888713be759858b74e8352031a9726707fa280b3812272508ef43ff8835fa2a0c8cd1382c4a02f8180eeea0e7ee99988f015291ccda9bba6a62636d273987812352bf512b31447fa2b2c90856efc3832243709d9f4cfb826e673b3142c4e2dec3388def5176da3955fa14bd11f9663e7e7e78fb8a12f39f0f3695808e2294502671e2e37d995333228c8b995f08fe54c724b7e985a60d8988fede4ede79bb46d3e8fcb48040e9b30bc64c6e122cf8526a134f9db56d8e178ff1a8a39450680acef4274c570f519fc9f61130147c5792fc0be6f6f6153698167afdbed8e4b29873ce5693a90a7512a0525c9df96c26a8dd08333d6c939038a8c5970de6f38e4ff194bde3ec29a884947678c8eeb37f112d0545c5cbc4fd3b4e440ef8cbe910dd7915fe0667eff0ee1b4dcad1d1ce1582b40ce2019c06c037d97ff8187be3283f74b3cd41c8e500fecaeaeaeeef8b84510471a93f229714bae4edd173589bdd8c4411cdb58b2ebca1952925a8a8d935c19f8e96e5e07b624eef2e8f9e79f7f467ddbea1e10ff0bcf2f427a24b334415db2ccb4b0f7f570b83dc61101bd2a073d89a96aa3c279e3ba8170e22ecdcaca4aef89a78d0c9abee89001f0d9c94cf46afc777fa180b049f48583ec0082ca592839e756ac3e991e6fe338920084659d997b5ebf18aa9e75b68fde88cfe7e26a2958942c570a5ac31c7db89ead3899b97de4a250cf7405001efb147ce133cef6772f42f83dccf7481e4c3da6374ef8a77b780f382c1c07987ec2857200191fe96ebe0a2efb0a886b9cdfff53cb451ec9e3405ef2184b616fefa471f587bc0bb42867c6ba9cebae20c3841cb81ece790ef883f33b7233177a246b85e0bcd4e39afb68bff3cfbc0e1cc27180252775c939648c90e012284de487beb808f9d9a9d47a258f4b416dea711d317a57ed60d3ce2e3e948203b6a2931c5e012e2384bc77f500192d5fc65deea3ce2bf989382eecb4374ee4378dfcf5f106de96827db6a2951c951d496484907f7ad9f90e2ec15be0e6f36ec9d3380ea77ef4c689ac6f62cb9d7fe26501fb6c45234e5044ce6956a9c8a896a5e02c4df018c79111b731df6c65e757dee645609f721249735690a722a3843cbd9b8e8321965bea5899a09c94858826e800f625be739e0cc82021f7d6c2b7fe4aecfa4dbcb4a79b27535526af86fbdfab98f7bbcb9907484b41d919b31764161923e47b5ba1cc8bdad24ed757dfe1a1963e7e9f5aae09bc574d65c9cfeaf857a0b44b47cb73e59effe37864b4cbead2513e17e6bb015a96fd8de55d3a5b53cbdd92c2ebce61d9f7e7b008288e9ae3848c3862a6e31afef57ef63e5ccfd2b0c947a9e5f92e26fc470df7947999468ec662a522e38424a080d80fb6b1f5b9fd2cd52d82c9c71e36d11b82f49678f82403b158394b4ada08494e4283f37087e3c9b381de5bde61d3a666be6b9a447b747a9fdfcf9f3eb3815f3586083010a6aa12ff99aeea8f1aa46d60a8699a3671e2c4e22baeb8a2fcf6db6f374a4b4b6ddb1eda184e0ac1ae964ef9c10b4fbc531cfae3d3cda1f8d45bf7f9dfa9ad2d6a9f397346f7e73ef739dfecd9b32bdd6eb77df0e0c1981022428ed9b4d24288104254545414af5fbffebaaaaaaa3abfdf1f95520eeb414d9c34894fd7fe58b6f7463cdece4eb14dc517959496868a8b8bfbdc6eb795b23cf66660238e5d2b67c628696b2145454545f3e6cd5b98b6eb1516503da9f2a4658661d8dddddd79c0361c67558c1c6929a345a80f099665c50f1f3e5c8a331d949b1c2103864948228c3463537f0b215c96657971727f732a606e585d56281452baae1f8c46a3d5baaebb1273659d11082144341a8d0583c120391e753268ac5ebd5a5fbd7af5ddc00ca00a279bf64cc2064252ca1edbb6738a94614d1c80f34022c07ee00867befb528069db762f39e6b01aae9625185884385373f62413496db24f86a88f1ba39d9290840017524af737bff9cd0be6cd9be79b3367ceb9050505166476b42c84c8bad1ba10826834aa0b216a841027f42ca724c4344d9452bacbe572af58b1e21edbb693339266db5b396a5058580810370c43eaba6e92129f7c4a429a9b9bed8e8e8e8d6d6d6de78442a1024065cb7a50a31cc2e5727976eedcd9c4406ac5a05673d670a698a9022ac8d2c1e42886e976bb038661b400d1c11022189828c633a2551b9b48ae241407aca1ca81f1d6917e1c33edc8ff0311504d2a89d602380000000049454e44ae426082 + + + + + + + + ShapeItem1 + + + + + ReportHeader1 + + + + + + + + + + + + ShapeItem2 + + + + + ReportHeader1 + + + + + + + + + + + + TextItem9 + + + + + ReportHeader1 + + + REPORT + + + + + + + + + + + + + + + TextItem10 + + + + + ReportHeader1 + + + HEADER + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + + + + DataBand1 + + + + TextItem3 + + + + + DataBand1 + + + $D{orders.OrderDate} + + + + + + + + + + + + + + + TextItem4 + + + + + DataBand1 + + + $D{orders.OrderID} + + + + + + + + + + + + + + + TextItem12 + + + + + DataBand1 + + + DATA BAND + + + + + + + + + + + + + + + TextItem16 + + + + + DataBand1 + + + OrderID + + + + + + + + + + + + + + + TextItem17 + + + + + DataBand1 + + + Order Date + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + orders + + + + + + + GroupBandHeader1 + + + + TextItem2 + + + + + GroupBandHeader1 + + + $D{orders.CompanyName} + + + + + + + + + + + + + + + ShapeItem3 + + + + + GroupBandHeader1 + + + + + + + + + + + + TextItem11 + + + + + GroupBandHeader1 + + + GROUP HEADER + + + + + + + + + + + + + + + + + ReportPage1 + + + + DataBand1 + + + CompanyName + + + + + SubDetailBand1 + + + + TextItem5 + + + + + SubDetailBand1 + + + $D{orderitems.ProductName} + + + + + + + + + + + + + + + TextItem6 + + + + + SubDetailBand1 + + + $D{orderitems.Quantity} + + + + + + + + + + + + + + + TextItem7 + + + + + SubDetailBand1 + + + $S{line("SubDetailBand1")} + + + + + + + + + + + + + + + TextItem13 + + + + + SubDetailBand1 + + + SUBDETAIL BAND + + + + + + + + + + + + + + + + + ReportPage1 + + + + DataBand1 + + + orderitems + + + + SubDetailFooterBand1 + + + + TextItem8 + + + + + SubDetailFooterBand1 + + + $S{SUM($D{orderitems.Quantity},"SubDetailBand1")} + + + + + + + + + + + + + + + TextItem14 + + + + + SubDetailFooterBand1 + + + SUBDETAIL FOOTER + + + + + + + + + + + + + + + TextItem15 + + + + + SubDetailFooterBand1 + + + Total + + + + + + + + + + + + + + + ShapeItem4 + + + + + SubDetailFooterBand1 + + + + + + + + + + + + + + ReportPage1 + + + + SubDetailBand1 + + + + + + + + + + + + + + + + + + + datasources + + + + northwind + QSQLITE + ./demo_reports/northwind.db + + + + + + + + + + orders + Select * from orders +inner join customers on customers.customerid = orders.customerid order by companyname +limit 50 + northwind + + + + + + orderitems + Select * from orderitems + inner join products on products.productid = orderitems.productid +where orderid = $D{orders.orderid} + northwind + orders + + + + + + + diff --git a/demo/r1/demo_reports/northwind.db b/demo/r1/demo_reports/northwind.db new file mode 100644 index 0000000..42a4ef6 Binary files /dev/null and b/demo/r1/demo_reports/northwind.db differ diff --git a/demo/r1/demo_reports/png/Beverage.png b/demo/r1/demo_reports/png/Beverage.png new file mode 100644 index 0000000..b818319 Binary files /dev/null and b/demo/r1/demo_reports/png/Beverage.png differ diff --git a/demo/r1/demo_reports/png/Condiments.png b/demo/r1/demo_reports/png/Condiments.png new file mode 100644 index 0000000..c658b6e Binary files /dev/null and b/demo/r1/demo_reports/png/Condiments.png differ diff --git a/demo/r1/demo_reports/png/Confections.png b/demo/r1/demo_reports/png/Confections.png new file mode 100644 index 0000000..11ca99c Binary files /dev/null and b/demo/r1/demo_reports/png/Confections.png differ diff --git a/demo/r1/demo_reports/png/Confections1.png b/demo/r1/demo_reports/png/Confections1.png new file mode 100644 index 0000000..55cc2e2 Binary files /dev/null and b/demo/r1/demo_reports/png/Confections1.png differ diff --git a/demo/r1/demo_reports/png/Confections2.png b/demo/r1/demo_reports/png/Confections2.png new file mode 100644 index 0000000..bc832a3 Binary files /dev/null and b/demo/r1/demo_reports/png/Confections2.png differ diff --git a/demo/r1/demo_reports/png/Dairy_Products.png b/demo/r1/demo_reports/png/Dairy_Products.png new file mode 100644 index 0000000..3e9088b Binary files /dev/null and b/demo/r1/demo_reports/png/Dairy_Products.png differ diff --git a/demo/r1/demo_reports/png/Grains_Cereals.png b/demo/r1/demo_reports/png/Grains_Cereals.png new file mode 100644 index 0000000..10d43ca Binary files /dev/null and b/demo/r1/demo_reports/png/Grains_Cereals.png differ diff --git a/demo/r1/demo_reports/png/Grains_Cereals1.png b/demo/r1/demo_reports/png/Grains_Cereals1.png new file mode 100644 index 0000000..514e33a Binary files /dev/null and b/demo/r1/demo_reports/png/Grains_Cereals1.png differ diff --git a/demo/r1/demo_reports/png/Meat_Poultry.png b/demo/r1/demo_reports/png/Meat_Poultry.png new file mode 100644 index 0000000..3a1d2ef Binary files /dev/null and b/demo/r1/demo_reports/png/Meat_Poultry.png differ diff --git a/demo/r1/demo_reports/png/Produce.png b/demo/r1/demo_reports/png/Produce.png new file mode 100644 index 0000000..8955fe9 Binary files /dev/null and b/demo/r1/demo_reports/png/Produce.png differ diff --git a/demo/r1/demo_reports/png/Seafood.png b/demo/r1/demo_reports/png/Seafood.png new file mode 100644 index 0000000..88fd48e Binary files /dev/null and b/demo/r1/demo_reports/png/Seafood.png differ diff --git a/demo/r1/images/logo.png b/demo/r1/images/logo.png new file mode 100644 index 0000000..a466bbb Binary files /dev/null and b/demo/r1/images/logo.png differ diff --git a/demo/r1/images/lr.png b/demo/r1/images/lr.png new file mode 100644 index 0000000..2206744 Binary files /dev/null and b/demo/r1/images/lr.png differ diff --git a/demo/r1/lr1.ico b/demo/r1/lr1.ico new file mode 100644 index 0000000..2eba2a4 Binary files /dev/null and b/demo/r1/lr1.ico differ diff --git a/demo/r1/lr2.ico b/demo/r1/lr2.ico new file mode 100644 index 0000000..2bc8699 Binary files /dev/null and b/demo/r1/lr2.ico differ diff --git a/demo/r1/lr3.ico b/demo/r1/lr3.ico new file mode 100644 index 0000000..7f11705 Binary files /dev/null and b/demo/r1/lr3.ico differ diff --git a/demo/r1/lr4.ico b/demo/r1/lr4.ico new file mode 100644 index 0000000..dd68ec8 Binary files /dev/null and b/demo/r1/lr4.ico differ diff --git a/demo/r1/lr5.ico b/demo/r1/lr5.ico new file mode 100644 index 0000000..e1bc436 Binary files /dev/null and b/demo/r1/lr5.ico differ diff --git a/demo/r1/lr6.ico b/demo/r1/lr6.ico new file mode 100644 index 0000000..6bd0818 Binary files /dev/null and b/demo/r1/lr6.ico differ diff --git a/demo/r1/main.cpp b/demo/r1/main.cpp new file mode 100644 index 0000000..06ac390 --- /dev/null +++ b/demo/r1/main.cpp @@ -0,0 +1,42 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "mainwindow.h" +#include + + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.setWindowIcon(QIcon(":/images/main_ico")); + w.show(); + + return a.exec(); +} diff --git a/demo/r1/main.ico b/demo/r1/main.ico new file mode 100644 index 0000000..6bd0818 Binary files /dev/null and b/demo/r1/main.ico differ diff --git a/demo/r1/mainicon.rc b/demo/r1/mainicon.rc new file mode 100644 index 0000000..83c0128 --- /dev/null +++ b/demo/r1/mainicon.rc @@ -0,0 +1 @@ +DI_ICON1 ICON "main.ico" diff --git a/demo/r1/mainwindow.cpp b/demo/r1/mainwindow.cpp new file mode 100644 index 0000000..2926572 --- /dev/null +++ b/demo/r1/mainwindow.cpp @@ -0,0 +1,196 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "mainwindow.h" +#include "ui_mainwindow.h" +#include +#include +#include +#include +#include "lrreportengine.h" +#include "lrcallbackdatasourceintf.h" +#include +#include + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow), m_progressDialog(0), m_customers(0), m_orders(0) +{ + ui->setupUi(this); + report = new LimeReport::ReportEngine(this); + + connect(report, SIGNAL(renderStarted()), this, SLOT(renderStarted())); + connect(report, SIGNAL(renderPageFinished(int)), + this, SLOT(renderPageFinished(int))); + connect(report, SIGNAL(renderFinished()), this, SLOT(renderFinished())); + + QFile dbFile(QApplication::applicationDirPath()+"/demo_reports/northwind.db"); + if (dbFile.exists()){ + m_db = QSqlDatabase::addDatabase("QSQLITE"); + m_db.setDatabaseName(dbFile.fileName()); + if (m_db.open()){ + QSqlQueryModel* customersModel = new QSqlQueryModel(); + customersModel->setQuery("select * from customers", m_db); + report->dataManager()->addModel("external_customers_data",customersModel,true); + QSqlQueryModel* ordersModel = new QSqlQueryModel(); + ordersModel->setQuery("Select * from orders",m_db); + report->dataManager()->addModel("external_orders_data",ordersModel,true); + m_customers = new QSqlQuery("Select * from customers limit 10",m_db); + m_customers->first(); + m_orders = new QSqlQuery(m_db); + m_orders->prepare("Select * from orders where CustomerID = :id"); + m_orders->bindValue(":id",m_customers->value("CustomerID")); + m_orders->exec(); + }; + } + + LimeReport::ICallbackDatasource * callbackDatasource = report->dataManager()->createCallbackDatasouce("master"); + connect(callbackDatasource, SIGNAL(getCallbackData(LimeReport::CallbackInfo,QVariant&)), + this, SLOT(slotGetCallbackData(LimeReport::CallbackInfo,QVariant&))); + connect(callbackDatasource, SIGNAL(changePos(const LimeReport::CallbackInfo::ChangePosType&,bool&)), + this, SLOT(slotChangePos(const LimeReport::CallbackInfo::ChangePosType&,bool&))); + //report->dataManager()->addCallbackDatasource(callbackDatasource,"master"); + + callbackDatasource = report->dataManager()->createCallbackDatasouce("detail"); + connect(callbackDatasource, SIGNAL(getCallbackData(LimeReport::CallbackInfo,QVariant&)), + this, SLOT(slotGetCallbackChildData(LimeReport::CallbackInfo,QVariant&))); + connect(callbackDatasource, SIGNAL(changePos(const LimeReport::CallbackInfo::ChangePosType&,bool&)), + this, SLOT(slotChangeChildPos(const LimeReport::CallbackInfo::ChangePosType&,bool&))); + //report->dataManager()->addCallbackDatasource(callbackDatasource,"detail"); + + QStringList simpleData; + simpleData << "value1" << "value2" << "value3"; + QStringListModel* stringListModel = new QStringListModel(); + stringListModel->setStringList(simpleData); + + report->dataManager()->addModel("string_list",stringListModel,true); + + +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::on_pushButton_clicked() +{ + report->dataManager()->clearUserVariables(); + if (!ui->leVariableName->text().isEmpty() && !ui->leVariableValue->text().isEmpty()){ + report->dataManager()->setReportVariable(ui->leVariableName->text(), ui->leVariableValue->text()); + } + report->setShowProgressDialog(false); + report->designReport(); +} + +void MainWindow::on_pushButton_2_clicked() +{ + QString fileName = QFileDialog::getOpenFileName(this,"Select report file",QApplication::applicationDirPath()+"/demo_reports/","*.lrxml"); + if (!fileName.isEmpty()) { + report->loadFromFile(fileName); + report->previewReport(); + } +} + +void MainWindow::renderStarted() +{ + m_currentPage = 0; + m_progressDialog = new QProgressDialog(tr("Start render"),tr("Cancel"),0,0,this); + m_progressDialog->setWindowModality(Qt::WindowModal); + connect(m_progressDialog, SIGNAL(canceled()), report, SLOT(cancelRender())); + m_progressDialog->show(); + QApplication::processEvents(); +} + +void MainWindow::renderPageFinished(int renderedPageCount) +{ + if (m_progressDialog){ + m_progressDialog->setLabelText(QString::number(renderedPageCount)+tr(" page rendered")); + m_progressDialog->setValue(renderedPageCount); + } +} + +void MainWindow::renderFinished() +{ + if (m_progressDialog){ + m_progressDialog->close(); + delete m_progressDialog; + } + m_progressDialog = 0; +} + +void MainWindow::prepareData(QSqlQuery* ds, LimeReport::CallbackInfo info, QVariant &data) +{ + switch (info.dataType) { + case LimeReport::CallbackInfo::IsEmpty: + data = !ds->first(); + break; + case LimeReport::CallbackInfo::HasNext: + data = ds->next(); + if (data.toBool()) ds->previous(); + break; + case LimeReport::CallbackInfo::ColumnHeaderData: + if (info.index < ds->record().count()) + data = ds->record().fieldName(info.index); + break; + case LimeReport::CallbackInfo::ColumnData: + data = ds->value(info.columnName); + break; + } +} + +void MainWindow::slotGetCallbackData(LimeReport::CallbackInfo info, QVariant &data) +{ + if (!m_customers) return; + prepareData(m_customers, info, data); +} + +void MainWindow::slotChangePos(const LimeReport::CallbackInfo::ChangePosType &type, bool &result) +{ + QSqlQuery* ds = m_customers; + if (!ds) return; + if (type == LimeReport::CallbackInfo::First) result = ds->first(); + else result = ds->next(); + m_orders->bindValue(":id",m_customers->value("CustomerID")); + m_orders->exec(); +} + +void MainWindow::slotGetCallbackChildData(LimeReport::CallbackInfo info, QVariant &data) +{ + if (!m_orders) return ; + prepareData(m_orders, info, data); +} + +void MainWindow::slotChangeChildPos(const LimeReport::CallbackInfo::ChangePosType &type, bool &result) +{ + QSqlQuery* ds = m_orders; + if (!ds) return; + if (type == LimeReport::CallbackInfo::First) result = ds->first(); + else result = ds->next(); +} diff --git a/demo/r1/mainwindow.h b/demo/r1/mainwindow.h new file mode 100644 index 0000000..e5bbd32 --- /dev/null +++ b/demo/r1/mainwindow.h @@ -0,0 +1,80 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include +#include "lrreportengine.h" + +namespace Ui { +class MainWindow; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = 0); + ~MainWindow(); +private slots: + void on_pushButton_clicked(); + void on_pushButton_2_clicked(); + void renderStarted(); + void renderPageFinished(int renderedPageCount); + void renderFinished(); + void slotGetCallbackData(LimeReport::CallbackInfo info, QVariant& data); + void slotChangePos(const LimeReport::CallbackInfo::ChangePosType& type, bool& result); + void slotGetCallbackChildData(LimeReport::CallbackInfo info, QVariant& data); + void slotChangeChildPos(const LimeReport::CallbackInfo::ChangePosType& type, bool& result); +private: + void prepareData(QSqlQuery* ds, LimeReport::CallbackInfo info, QVariant &data); +private: + Ui::MainWindow *ui; + LimeReport::ReportEngine *report; + QProgressDialog* m_progressDialog; + int m_currentPage; + QSqlDatabase m_db; + int m_currentMasterRecord; + QVector m_childData; + + int m_currentCustomerRecord; + int m_currentOrderRecord; + QSqlQuery* m_customers; + QSqlQuery* m_orders; + +}; + + + +#endif // MAINWINDOW_H diff --git a/demo/r1/mainwindow.ui b/demo/r1/mainwindow.ui new file mode 100644 index 0000000..52eebe9 --- /dev/null +++ b/demo/r1/mainwindow.ui @@ -0,0 +1,213 @@ + + + MainWindow + + + + 0 + 0 + 369 + 192 + + + + + 75 + true + + + + DEMO + + + + + + + + + + + + 0 + 0 + + + + + 100 + 100 + + + + + + + :/images/logo + + + true + + + + + + + + + + + Report setting + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + TestName + + + + + + + Variable Value + + + + + + + TestValue + + + + + + + Variable Name + + + + + + + + + + + + Qt::Vertical + + + + 160 + 23 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Run Report Preview + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Run Report Designer + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 160 + 28 + + + + + + + + + + + + + + + + + diff --git a/demo/r1/r1.pro b/demo/r1/r1.pro new file mode 100644 index 0000000..36665f2 --- /dev/null +++ b/demo/r1/r1.pro @@ -0,0 +1,44 @@ +QT += core gui script sql + +EXTRA_DIR += $$PWD/demo_reports/* + +win32:CONFIG(release, debug|release): DEST_DIR = $$OUT_PWD/demo_reports/ +win32:CONFIG(debug, debug|release): DEST_DIR = $$OUT_PWD/demo_reports/ + +unix{ + DEST_DIR = $$OUT_PWD/demo_reports/ + QMAKE_POST_LINK += mkdir -p $$quote($$DEST_DIR) | $$QMAKE_COPY_DIR $$quote($$EXTRA_DIR) $$quote($$DEST_DIR) $$escape_expand(\n\t) +} + +win32 { + EXTRA_DIR ~= s,/,\\,g + DEST_DIR ~= s,/,\\,g + QMAKE_POST_LINK += $$QMAKE_COPY_DIR $$quote($$EXTRA_DIR) $$quote($$DEST_DIR) $$escape_expand(\\n\\t) +} + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport + +TARGET = r1 +TEMPLATE = app + +SOURCES += main.cpp\ + mainwindow.cpp + +HEADERS += mainwindow.h + +FORMS += mainwindow.ui + +win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../lib/release -llimereport +else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../lib/debug -llimereport +else:unix:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../lib/debug -llimereport +else:unix:CONFIG(release, debug|release): LIBS += -L$$PWD/../../lib/release -llimereport + +INCLUDEPATH += $$PWD/../../include +DEPENDPATH += $$PWD/../../include + +RESOURCES += \ + r1.qrc + +win32 { + RC_FILE += mainicon.rc +} \ No newline at end of file diff --git a/demo/r1/r1.qrc b/demo/r1/r1.qrc new file mode 100644 index 0000000..1e604e8 --- /dev/null +++ b/demo/r1/r1.qrc @@ -0,0 +1,9 @@ + + + images/logo.png + main.ico + images/lr.png + lr1.ico + lr6.ico + + diff --git a/include/lrcallbackdatasourceintf.h b/include/lrcallbackdatasourceintf.h new file mode 100644 index 0000000..3259f4b --- /dev/null +++ b/include/lrcallbackdatasourceintf.h @@ -0,0 +1,24 @@ +#ifndef LRVIRTUALDATASOURCEINTF +#define LRVIRTUALDATASOURCEINTF +#include +namespace LimeReport { + +struct CallbackInfo{ + enum DataType{IsEmpty, HasNext, ColumnHeaderData, ColumnData}; + enum ChangePosType{First, Next}; + DataType dataType; + int index; + QString columnName; +}; + +class ICallbackDatasource :public QObject{ + Q_OBJECT +signals: + void getCallbackData(const LimeReport::CallbackInfo& info, QVariant& data); + void changePos(const LimeReport::CallbackInfo::ChangePosType& type, bool& result); +}; + +} + +#endif // LRVIRTUALDATASOURCEINTF + diff --git a/include/lrdatasourcemanagerintf.h b/include/lrdatasourcemanagerintf.h new file mode 100644 index 0000000..123f049 --- /dev/null +++ b/include/lrdatasourcemanagerintf.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRDATASOURCEMANAGERINTF_H +#define LRDATASOURCEMANAGERINTF_H + +#include "lrcallbackdatasourceintf.h" + +class QVariant; +class QString; +class QAbstractItemModel; +namespace LimeReport{ + +class IDataSourceManager{ +public: + virtual void setReportVariable(const QString& name, const QVariant& value)=0; + virtual void deleteVariable(const QString& name)=0; + virtual bool containsVariable(const QString& variableName)=0; + virtual QVariant variable(const QString& variableName)=0; + virtual void addModel(const QString& name, QAbstractItemModel *model, bool owned)=0; + virtual bool containsDatasource(const QString& dataSourceName)=0; + virtual void clearUserVariables()=0; + virtual ICallbackDatasource* createCallbackDatasouce(const QString& name) = 0; + virtual void addCallbackDatasource(ICallbackDatasource* datasource, const QString& name) = 0; +}; + +} +#endif // LRDATASOURCEMANAGERINTF_H diff --git a/include/lrglobal.cpp b/include/lrglobal.cpp new file mode 100644 index 0000000..34bd880 --- /dev/null +++ b/include/lrglobal.cpp @@ -0,0 +1,40 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include +#include +#include "lrglobal.h" + +QString LimeReport::extractClassName(QString className) +{ + int startPos=className.lastIndexOf("::"); + if(startPos==-1) startPos=0; + else startPos+=2; + return className.right(className.length()-startPos); +} diff --git a/include/lrglobal.h b/include/lrglobal.h new file mode 100644 index 0000000..a701619 --- /dev/null +++ b/include/lrglobal.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef GLOBAL_H +#define GLOBAL_H +#include "qglobal.h" +#include +#include + +#if defined(LIMEREPORT_EXPORTS) +# define LIMEREPORT_EXPORT Q_DECL_EXPORT +#elif defined (LIMEREPORT_IMPORTS) +# define LIMEREPORT_EXPORT Q_DECL_IMPORT +#else +# define LIMEREPORT_EXPORT /**/ +#endif + +namespace LimeReport { + const qreal fontFACTOR = 3.5; + const int mmFACTOR = 10; + const int itemPaleteIconSize = 24; + const qreal minSpaceBorder = 10; + QString extractClassName(QString className); + const QString bandTAG = "band"; + const qreal BAND_MARKER_OPACITY = 1; + const qreal LAYOUT_MARKER_OPACITY = 0.3; + const qreal BAND_NAME_AREA_OPACITY = 0.3; + const qreal BAND_NAME_TEXT_OPACITY = 0.6; + const qreal SELECTION_OPACITY = 0.3; + enum RenderPass {FirstPass, SecondPass}; + enum ArrangeType {AsNeeded, Force}; + const QString FIELD_RX = "\\$D\\s*\\{\\s*([^\\s{}]*)\\s*\\}"; + const QString VARIABLE_RX = "\\$V\\s*\\{\\s*([^\\s{}]*)\\s*\\}"; + const QString SCRIPT_RX = "\\$S\\s*\\{(.*)\\}"; + const QString GROUP_FUNCTION_PARAM_RX = "\\(\\s*(((?:\\\"?\\$D\\s*\\{\\s*)|(?:\\\"?\\$V\\s*\\{\\s*)|(?:\\\"))(\\w+\\.?\\w+)((?:\\\")|(?:\\s*\\}\\\"?\\s*)))\\s*,\\s*\\\"(\\w+)\\\"\\s*\\)"; + const int DATASOURCE_INDEX = 6; + const int VALUE_INDEX = 2; + const QString GROUP_FUNCTION_RX = "(%1\\s*"+GROUP_FUNCTION_PARAM_RX+")"; + const QString GROUP_FUNCTION_NAME_RX = "%1\\s*\\((.*[^\\)])\\)"; + const int SCENE_MARGIN = 50; + class ReportError : public std::runtime_error{ + public: + ReportError(const QString& message):std::runtime_error(message.toStdString()){} + }; + +} // namespace LimeReport + + + +#endif // GLOBAL_H diff --git a/include/lrreportengine.h b/include/lrreportengine.h new file mode 100644 index 0000000..924976a --- /dev/null +++ b/include/lrreportengine.h @@ -0,0 +1,105 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRREPORTDESIGNINTF_H +#define LRREPORTDESIGNINTF_H + +#include +#include +#include + +#include "lrglobal.h" +#include "lrdatasourcemanagerintf.h" +#include "lrscriptenginemanagerintf.h" +//#include "lrreportrender.h" + +class QPrinter; + +namespace LimeReport { + + +class PrintRange{ +public: + int fromPage() const { return m_fromPage;} + int toPage() const { return m_toPage;} + QPrintDialog::PrintRange rangeType() const { return m_rangeType;} + PrintRange(QAbstractPrintDialog::PrintRange rangeType=QPrintDialog::AllPages, int fromPage=0, int toPage=0); + void setRangeType(QAbstractPrintDialog::PrintRange rangeType){ m_rangeType=rangeType;} + void setFromPage(int fromPage){ m_fromPage = fromPage;} + void setToPage(int toPage){ m_toPage = toPage;} +private: + QPrintDialog::PrintRange m_rangeType; + int m_fromPage; + int m_toPage; +}; + +class DataSourceManager; +class ReportEnginePrivate; +//class PageDesignIntf; + +class LIMEREPORT_EXPORT ReportEngine : public QObject{ + Q_OBJECT +public: + static void setSettings(QSettings *value){m_settings=value;} +public: + explicit ReportEngine(QObject *parent = 0); + ~ReportEngine(); + bool printReport(QPrinter *printer=0); + //void printReport(ReportPages pages, QPrinter &printer); + void printToFile(const QString& fileName); + //PageDesignIntf *createPreviewScene(QObject *parent = 0); + void previewReport(); + void designReport(); + void setShowProgressDialog(bool value); + IDataSourceManager* dataManager(); + IScriptEngineManager* scriptManager(); + + bool loadFromFile(const QString& fileName); + bool loadFromByteArray(QByteArray *data); + QString reportFileName(); + bool saveToFile(); + bool saveToFile(const QString& fileName); + QString lastError(); +signals: + void renderStarted(); + void renderFinished(); + void renderPageFinished(int renderedPageCount); +public slots: + void cancelRender(); +protected: + ReportEnginePrivate * const d_ptr; + ReportEngine(ReportEnginePrivate &dd, QObject * parent=0); +private: + Q_DECLARE_PRIVATE(ReportEngine) + static QSettings* m_settings; +}; + +} // namespace LimeReport + +#endif // LRREPORTDESIGNINTF_H diff --git a/include/lrscriptenginemanagerintf.h b/include/lrscriptenginemanagerintf.h new file mode 100644 index 0000000..56284da --- /dev/null +++ b/include/lrscriptenginemanagerintf.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRSCRIPTENGINEMANAGERINTF_H +#define LRSCRIPTENGINEMANAGERINTF_H + +#include + +namespace LimeReport{ + +class IScriptEngineManager{ +public: + virtual QScriptEngine* scriptEngine() = 0; + virtual QScriptValue addFunction(const QString& name, QScriptEngine::FunctionSignature function, + const QString& category="", const QString& description="") = 0; + virtual QScriptValue addFunction(const QString &name, const QString& script, + const QString &category="", const QString &description="") = 0; + virtual const QString& lastError() const = 0; + virtual ~IScriptEngineManager(){} +}; + +} //namespace LimeReport +#endif // LRSCRIPTENGINEMANAGERINTF_H diff --git a/lib/.gitignore b/lib/.gitignore new file mode 100644 index 0000000..591459e --- /dev/null +++ b/lib/.gitignore @@ -0,0 +1,5 @@ +release/* +debug/* +*.so.1.0.0.debug +*.so.1.0.0 +/ReportGenerator.app/ diff --git a/limereport.pro b/limereport.pro new file mode 100644 index 0000000..6ae3a53 --- /dev/null +++ b/limereport.pro @@ -0,0 +1,45 @@ +#CONFIG +=zint +#QMAKE_CFLAGS += -std=c99 +#ZINT_PATH = $$PWD/../zint-2.4.3 +#ZINT_VERSION = 2.4.3 +#include(qzint.pri) +include(report-lib.pri) + +TEMPLATE = lib +QT += core xml sql script +TARGET = limereport + +DEFINES += LIMEREPORT_EXPORTS + +EXTRA_FILES += \ + $$PWD/src/lrglobal.cpp \ + $$PWD/src/lrglobal.h \ + $$PWD/src/lrdatasourcemanagerintf.h \ + $$PWD/src/lrreportengine.h \ + $$PWD/src/lrscriptenginemanagerintf.h \ + $$PWD/src/lrcallbackdatasourceintf.h + +DEST_DIR = $$PWD/include/ + +unix { + for(FILE,EXTRA_FILES){ + QMAKE_POST_LINK += $$quote($$QMAKE_COPY $${FILE} $${DEST_DIR}$$escape_expand(\n\t)) + } +} + +win32 { + EXTRA_FILES ~= s,/,\\,g + DEST_DIR ~= s,/,\\,g + for(FILE,EXTRA_FILES){ + QMAKE_POST_LINK += $$QMAKE_COPY $$quote($$FILE) $$quote($$DEST_DIR) $$escape_expand(\\n\\t) + } +} + +DESTDIR = $$PWD/lib + +DEPENDPATH += report report/bands report/base report/databrowser report/items report/objectinspector +INCLUDEPATH += report report/bands report/base report/databrowser report/items report/objectinspector + +CONFIG(release, debug|release): DESTDIR = $$PWD/lib/release/ +else:CONFIG(debug, debug|release): DESTDIR = $$PWD/lib/debug/ + diff --git a/qzint.pri b/qzint.pri new file mode 100644 index 0000000..51a6a50 --- /dev/null +++ b/qzint.pri @@ -0,0 +1,64 @@ +DEFINES += _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS ZINT_VERSION=\\\"$$ZINT_VERSION\\\" NO_PNG + +!contains(DEFINES, NO_PNG) { + LIBS += -lpng +} + +INCLUDEPATH += \ + $$ZINT_PATH/backend \ + $$ZINT_PATH/backend_qt4 + +HEADERS += $$ZINT_PATH/backend/aztec.h \ + $$ZINT_PATH/backend/code1.h \ + $$ZINT_PATH/backend/code49.h \ + $$ZINT_PATH/backend/common.h \ + $$ZINT_PATH/backend/composite.h \ + $$ZINT_PATH/backend/dmatrix.h \ + $$ZINT_PATH/backend/font.h \ + $$ZINT_PATH/backend/gb2312.h \ + $$ZINT_PATH/backend/gridmtx.h \ + $$ZINT_PATH/backend/gs1.h \ + $$ZINT_PATH/backend/large.h \ + $$ZINT_PATH/backend/maxicode.h \ + $$ZINT_PATH/backend/maxipng.h \ + $$ZINT_PATH/backend/ms_stdint.h \ + $$ZINT_PATH/backend/pdf417.h \ + $$ZINT_PATH/backend/qr.h \ + $$ZINT_PATH/backend/reedsol.h \ + $$ZINT_PATH/backend/rss.h \ + $$ZINT_PATH/backend/sjis.h \ + $$ZINT_PATH/backend/zint.h \ + $$ZINT_PATH/backend_qt4/qzint.h + +SOURCES += $$ZINT_PATH/backend/2of5.c \ + $$ZINT_PATH/backend/auspost.c \ + $$ZINT_PATH/backend/aztec.c \ + $$ZINT_PATH/backend/code.c \ + $$ZINT_PATH/backend/code1.c \ + $$ZINT_PATH/backend/code128.c \ + $$ZINT_PATH/backend/code16k.c \ + $$ZINT_PATH/backend/code49.c \ + $$ZINT_PATH/backend/common.c \ + $$ZINT_PATH/backend/composite.c \ + $$ZINT_PATH/backend/dmatrix.c \ + $$ZINT_PATH/backend/gridmtx.c \ + $$ZINT_PATH/backend/gs1.c \ + $$ZINT_PATH/backend/imail.c \ + $$ZINT_PATH/backend/large.c \ + $$ZINT_PATH/backend/library.c \ + $$ZINT_PATH/backend/maxicode.c \ + $$ZINT_PATH/backend/medical.c \ + $$ZINT_PATH/backend/pdf417.c \ + $$ZINT_PATH/backend/plessey.c \ + $$ZINT_PATH/backend/postal.c \ + $$ZINT_PATH/backend/ps.c \ + $$ZINT_PATH/backend/qr.c \ + $$ZINT_PATH/backend/reedsol.c \ + $$ZINT_PATH/backend/render.c \ + $$ZINT_PATH/backend/rss.c \ + $$ZINT_PATH/backend/svg.c \ + $$ZINT_PATH/backend/telepen.c \ + $$ZINT_PATH/backend/upcean.c \ + $$ZINT_PATH/backend/dllversion.c \ + $$ZINT_PATH/backend/png.c \ + $$ZINT_PATH/backend_qt4/qzint.cpp diff --git a/report-lib.pri b/report-lib.pri new file mode 100644 index 0000000..5563ea5 --- /dev/null +++ b/report-lib.pri @@ -0,0 +1,228 @@ +QT += script xml sql +REPORT_PATH = $$PWD + +LIMEREPORT_VERSION_MAJOR = 1 +LIMEREPORT_VERSION_MINOR = 0 +LIMEREPORT_VERSION_RELEASE = 1 + +LIMEREPORT_VERSION = '\\"$${LIMEREPORT_VERSION_MAJOR}.$${LIMEREPORT_VERSION_MINOR}.$${LIMEREPORT_VERSION_RELEASE}\\"' +DEFINES += LIMEREPORT_VERSION_STR=\"$${LIMEREPORT_VERSION}\" +DEFINES += LIMEREPORT_VERSION=$${LIMEREPORT_VERSION} + +greaterThan(QT_MAJOR_VERSION, 4) { + DEFINES+=HAVE_QT5 + QT+= printsupport widgets + + contains(QT,uitools){ + message(uitools) + DEFINES += HAVE_UI_LOADER + } +} + +lessThan(QT_MAJOR_VERSION, 5){ + CONFIG(uitools){ + message(uitools) + DEFINES += HAVE_UI_LOADER + } +} + +DEFINES += INSPECT_BASEDESIGN + +REPORT_PATH = $$PWD/src + +INCLUDEPATH += \ + $$REPORT_PATH/ \ + $$REPORT_PATH/items \ + $$REPORT_PATH/bands \ + $$REPORT_PATH/base \ + $$REPORT_PATH/objectinspector \ + $$REPORT_PATH/databrowser + +SOURCES += \ + $$REPORT_PATH/items/lrtextitem.cpp \ + $$REPORT_PATH/bands/lrpageheader.cpp \ + $$REPORT_PATH/bands/lrpagefooter.cpp \ + $$REPORT_PATH/bands/lrreportheader.cpp \ + $$REPORT_PATH/bands/lrreportfooter.cpp \ + $$REPORT_PATH/bands/lrdataband.cpp \ + $$REPORT_PATH/bands/lrgroupbands.cpp \ + $$REPORT_PATH/bands/lrsubdetailband.cpp \ + $$REPORT_PATH/objectinspector/lrobjectinspectorwidget.cpp \ + $$REPORT_PATH/objectinspector/lrobjectitemmodel.cpp \ + $$REPORT_PATH/objectinspector/lrobjectpropitem.cpp \ + $$REPORT_PATH/objectinspector/lrpropertydelegate.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrstringpropitem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrrectproptem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrintpropitem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrenumpropitem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrboolpropitem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrflagspropitem.cpp \ + $$REPORT_PATH/objectinspector/editors/lrtextitempropertyeditor.cpp \ + $$REPORT_PATH/objectinspector/editors/lrcomboboxeditor.cpp \ + $$REPORT_PATH/objectinspector/editors/lrcheckboxeditor.cpp \ + $$REPORT_PATH/objectinspector/editors/lrbuttonlineeditor.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrfontpropitem.cpp \ + $$REPORT_PATH/objectinspector/editors/lrfonteditor.cpp \ + $$REPORT_PATH/objectinspector/editors/lrimageeditor.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrimagepropitem.cpp \ + $$REPORT_PATH/objectinspector/lrbasedesignobjectmodel.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrqrealpropitem.cpp \ + $$REPORT_PATH/objectinspector/editors/lrcoloreditor.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrcolorpropitem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrdatasourcepropitem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrgroupfieldpropitem.cpp \ + $$REPORT_PATH/objectsbrowser/lrobjectbrowser.cpp \ + $$REPORT_PATH/databrowser/lrdatabrowser.cpp \ + $$REPORT_PATH/databrowser/lrsqleditdialog.cpp \ + $$REPORT_PATH/databrowser/lrconnectiondialog.cpp \ + $$REPORT_PATH/databrowser/lrvariabledialog.cpp \ + $$REPORT_PATH/databrowser/lrdatabrowsertree.cpp \ + $$REPORT_PATH/serializators/lrxmlqrectserializator.cpp \ + $$REPORT_PATH/serializators/lrxmlbasetypesserializators.cpp \ + $$REPORT_PATH/serializators/lrxmlreader.cpp \ + $$REPORT_PATH/serializators/lrxmlwriter.cpp \ + $$REPORT_PATH/items/lrsubitemparentpropitem.cpp \ + $$REPORT_PATH/items/lralignpropitem.cpp \ + $$REPORT_PATH/items/lrhorizontallayout.cpp \ + $$REPORT_PATH/items/editors/lritemeditorwidget.cpp \ + $$REPORT_PATH/items/editors/lrfonteditorwidget.cpp \ + $$REPORT_PATH/items/editors/lrtextalignmenteditorwidget.cpp \ + $$REPORT_PATH/items/editors/lritemsaligneditorwidget.cpp \ + $$REPORT_PATH/items/editors/lritemsborderseditorwidget.cpp \ + $$REPORT_PATH/items/lrsimpletagparser.cpp \ + $$REPORT_PATH/items/lrimageitem.cpp \ + $$REPORT_PATH/items/lrtextitemeditor.cpp \ + $$REPORT_PATH/items/lrshapeitem.cpp \ + $$REPORT_PATH/lrbanddesignintf.cpp \ + $$REPORT_PATH/lrpageitemdesignintf.cpp \ + $$REPORT_PATH/lrpagedesignintf.cpp \ + $$REPORT_PATH/lrbandsmanager.cpp \ + $$REPORT_PATH/lrglobal.cpp \ + $$REPORT_PATH/lritemdesignintf.cpp \ + $$REPORT_PATH/lrdatadesignintf.cpp \ + $$REPORT_PATH/lrreportdesignwidget.cpp \ + $$REPORT_PATH/lrbasedesignintf.cpp \ + $$REPORT_PATH/lrreportengine.cpp \ + $$REPORT_PATH/lrdatasourcemanager.cpp \ + $$REPORT_PATH/lrreportdesignwindow.cpp \ + $$REPORT_PATH/waitform.cpp \ + $$REPORT_PATH/lrreportrender.cpp \ + $$REPORT_PATH/lrscriptenginemanager.cpp \ + $$REPORT_PATH/lrpreviewreportwindow.cpp \ + $$REPORT_PATH/lrvariablesholder.cpp \ + $$REPORT_PATH/lrgroupfunctions.cpp \ + $$REPORT_PATH/lrsimplecrypt.cpp \ + $$REPORT_PATH/lraboutdialog.cpp + +contains(CONFIG, zint){ + SOURCES += $$REPORT_PATH/items/lrbarcodeitem.cpp +} + +HEADERS += \ + $$REPORT_PATH/base/lrsingleton.h \ + $$REPORT_PATH/bands/lrpageheader.h \ + $$REPORT_PATH/bands/lrpagefooter.h \ + $$REPORT_PATH/bands/lrreportheader.h \ + $$REPORT_PATH/bands/lrreportfooter.h \ + $$REPORT_PATH/bands/lrdataband.h \ + $$REPORT_PATH/objectinspector/lrobjectinspectorwidget.h \ + $$REPORT_PATH/objectinspector/lrobjectitemmodel.h \ + $$REPORT_PATH/objectinspector/lrobjectpropitem.h \ + $$REPORT_PATH/objectinspector/lrpropertydelegate.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrstringpropitem.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrrectproptem.h \ + $$REPORT_PATH/databrowser/lrdatabrowser.h \ + $$REPORT_PATH/databrowser/lrsqleditdialog.h \ + $$REPORT_PATH/databrowser/lrconnectiondialog.h \ + $$REPORT_PATH/databrowser/lrvariabledialog.h \ + $$REPORT_PATH/databrowser/lrdatabrowsertree.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrdatasourcepropitem.h \ + $$REPORT_PATH/lrbanddesignintf.h \ + $$REPORT_PATH/lrpageitemdesignintf.h \ + $$REPORT_PATH/lrbandsmanager.h \ + $$REPORT_PATH/lrglobal.h \ + $$REPORT_PATH/base/lrsimpleabstractfactory.h \ + $$REPORT_PATH/base/lrattribsabstractfactory.h \ + $$REPORT_PATH/serializators/lrserializatorintf.h \ + $$REPORT_PATH/serializators/lrstorageintf.h \ + $$REPORT_PATH/serializators/lrxmlqrectserializator.h \ + $$REPORT_PATH/serializators/lrxmlserializatorsfactory.h \ + $$REPORT_PATH/serializators/lrxmlbasetypesserializators.h \ + $$REPORT_PATH/serializators/lrxmlreader.h \ + $$REPORT_PATH/serializators/lrxmlwriter.h \ + $$REPORT_PATH/lrbasedesignintf.h \ + $$REPORT_PATH/lritemdesignintf.h \ + $$REPORT_PATH/lrdesignelementsfactory.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrintpropitem.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrenumpropitem.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrboolpropitem.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrflagspropitem.h \ + $$REPORT_PATH/objectinspector/editors/lrtextitempropertyeditor.h \ + $$REPORT_PATH/objectinspector/editors/lrcomboboxeditor.h \ + $$REPORT_PATH/objectinspector/editors/lrcheckboxeditor.h \ + $$REPORT_PATH/objectinspector/editors/lrbuttonlineeditor.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrgroupfieldpropitem.h \ + $$REPORT_PATH/objectsbrowser/lrobjectbrowser.h \ + $$REPORT_PATH/items/lrtextitem.h \ + $$REPORT_PATH/items/lrsubitemparentpropitem.h \ + $$REPORT_PATH/items/lralignpropitem.h \ + $$REPORT_PATH/items/lrhorizontallayout.h \ + $$REPORT_PATH/items/editors/lritemeditorwidget.h \ + $$REPORT_PATH/items/editors/lrfonteditorwidget.h \ + $$REPORT_PATH/items/editors/lrtextalignmenteditorwidget.h \ + $$REPORT_PATH/items/editors/lritemsaligneditorwidget.h \ + $$REPORT_PATH/items/editors/lritemsborderseditorwidget.h \ + $$REPORT_PATH/lrdatadesignintf.h \ + $$REPORT_PATH/lrcollection.h \ + $$REPORT_PATH/lrpagedesignintf.h \ + $$REPORT_PATH/lrreportdesignwidget.h \ + $$REPORT_PATH/lrreportengine_p.h \ + $$REPORT_PATH/lrdatasourcemanager.h \ + $$REPORT_PATH/lrreportdesignwindow.h \ + $$REPORT_PATH/waitform.h \ + $$REPORT_PATH/items/lrsimpletagparser.h \ + $$REPORT_PATH/bands/lrsubdetailband.h \ + $$REPORT_PATH/lrreportrender.h \ + $$REPORT_PATH/lrpreviewreportwindow.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrfontpropitem.h \ + $$REPORT_PATH/objectinspector/editors/lrfonteditor.h \ + $$REPORT_PATH/items/lrimageitem.h \ + $$REPORT_PATH/objectinspector/editors/lrimageeditor.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrimagepropitem.h \ + $$REPORT_PATH/items/lrtextitemeditor.h \ + $$REPORT_PATH/objectinspector/lrbasedesignobjectmodel.h \ + $$REPORT_PATH/lrscriptenginemanager.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrqrealpropitem.h \ + $$REPORT_PATH/items/lrshapeitem.h \ + $$REPORT_PATH/objectinspector/editors/lrcoloreditor.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrcolorpropitem.h \ + $$REPORT_PATH/bands/lrgroupbands.h \ + $$REPORT_PATH/lrvariablesholder.h \ + $$REPORT_PATH/lrgroupfunctions.h \ + $$REPORT_PATH/lrreportengine.h \ + $$REPORT_PATH/lrdatasourcemanagerintf.h \ + $$REPORT_PATH/lrscriptenginemanagerintf.h \ + $$REPORT_PATH/lrsimplecrypt.h \ + $$REPORT_PATH/lraboutdialog.h \ + $$REPORT_PATH/lrcallbackdatasourceintf.h + +contains(CONFIG,zint){ + HEADERS += $$REPORT_PATH/items/lrbarcodeitem.h +} + +FORMS += \ + $$REPORT_PATH/databrowser/lrsqleditdialog.ui \ + $$REPORT_PATH/databrowser/lrconnectiondialog.ui \ + $$REPORT_PATH/databrowser/lrdatabrowser.ui \ + $$REPORT_PATH/databrowser/lrvariabledialog.ui \ + $$REPORT_PATH/objectinspector/editors/ltextitempropertyeditor.ui \ + $$REPORT_PATH/waitform.ui \ + $$REPORT_PATH/lrpreviewreportwindow.ui \ + $$REPORT_PATH/items/lrtextitemeditor.ui \ + $$REPORT_PATH/lraboutdialog.ui + +RESOURCES += \ + $$REPORT_PATH/objectinspector/lobjectinspector.qrc \ + $$REPORT_PATH/databrowser/lrdatabrowser.qrc \ + $$REPORT_PATH/report.qrc \ + $$REPORT_PATH/items/items.qrc diff --git a/report-lib_ru.ts b/report-lib_ru.ts new file mode 100644 index 0000000..bc69495 --- /dev/null +++ b/report-lib_ru.ts @@ -0,0 +1,1466 @@ + + + + + ConnectionDialog + + + + Connection + Подключение + + + + Connection Name + Название соединения + + + + Driver + Драйвер + + + + Server + Сервер + + + + User + Пользователь + + + + Password + Пароль + + + + Database + База данных + + + + ... + + + + + Auto connect + Авто соединение + + + + Check connection + Проверить соединение + + + + Cancel + Отмена + + + + Ok + + + + + + Error + Ошибка + + + + Connection succsesfully established! + Соединение успешно установлено ! + + + + Connection Name is empty + Название соединения не указано + + + + Connection with name + Соединение с названием + + + + already exists + уже существует + + + + DataBrowser + + + + Datasources + + + + + Add database connection + + + + + + + + + + + + + + + + ... + + + + + Variables + + + + + LRVariableDialog + + + Variable + + + + + Name + + + + + Value + + + + + Type + + + + + Attention + + + + + LimeReport::AVariablesHolder + + + + + + variable with name + + + + + already exists !! + + + + + + + does not exists !! + + + + + LimeReport::AlignmentPropItem + + + Left + + + + + Right + + + + + + Center + + + + + Justify + + + + + Top + + + + + Botom + + + + + horizontal + + + + + vertical + + + + + LimeReport::ContentItemDesignIntf + + + Variable %1 not found + + + + + LimeReport::DataBand + + + Data + + + + + LimeReport::DataBrowser + + + Datasources + + + + + + + + Attention + + + + + Do you really want delete "%1" connection ? + + + + + User variables + + + + + System variables + + + + + Do you really want delete "%1" datasource ? + + + + + Do you really want delete variable "%1" ? + + + + + Error + + + + + LimeReport::DataSourceManager + + + + Datasource "%1" not found ! + + + + + connection with name "%1" already exists ! + + + + + data source with name "%1" already exists !! + + + + + datasource with name "%1"already exists !! + + + + + + datasource with name "%1" already exists !! + + + + + invalid connection + + + + + LimeReport::DataSourceModel + + + Datasources + + + + + Variables + + + + + LimeReport::FontEditorWidget + + + Font bold + + + + + Font Italic + + + + + Font Underline + + + + + LimeReport::FontPropItem + + + bold + + + + + italic + + + + + underline + + + + + size + + + + + family + + + + + LimeReport::GroupBandFooter + + + GroupFooter + + + + + LimeReport::GroupBandHeader + + + GroupHeader + + + + + LimeReport::GroupFunction + + + Field "%1" not found + + + + + Variable "%1" not found + + + + + Item "%1" not found + + + + + LimeReport::ItemsAlignmentEditorWidget + + + Bring to top + + + + + Send to back + + + + + Align to left + + + + + Align to right + + + + + Align to vertical center + + + + + Align to top + + + + + Align to bottom + + + + + Align to horizontal center + + + + + Set same height + + + + + Set same width + + + + + LimeReport::ItemsBordersEditorWidget + + + + + + Top line + + + + + No borders + + + + + All borders + + + + + LimeReport::MasterDetailProxyModel + + + Field: "%1" not found in "%2" child datasource + + + + + Field: "%1" not found in "%2" master datasource + + + + + LimeReport::ModelToDataSource + + + model i s destroyed + + + + + LimeReport::ObjectBrowser + + + Objects + + + + + LimeReport::PageDesignIntf + + + Attention! + + + + + Elements have different parent containers + + + + + LimeReport::PageFooter + + + Page Footer + + + + + LimeReport::PageHeader + + + Page Header + + + + + LimeReport::QObjectPropertyModel + + + Property Name + + + + + Property value + + + + + LimeReport::RectMMPropItem + + + + + width + + + + + + + height + + + + + LimeReport::RectPropItem + + + width + + + + + height + + + + + LimeReport::ReportDesignIntfPrivate + + + Error + + + + + LimeReport::ReportDesignWidget + + + + Page + + + + + Script + + + + + Report file name + + + + + Error + + + + + Wrong file format + + + + + LimeReport::ReportDesignWindow + + + New Report + + + + + New Report Page + + + + + Edit Mode + + + + + Undo + + + + + Redo + + + + + Copy + + + + + Paste + + + + + Cut + + + + + Text Item + + + + + Save Report + + + + + Save Report As + + + + + Load Report + + + + + Delete item + + + + + Zoom In + + + + + Zoom Out + + + + + Render Report + + + + + Edit layouts mode + + + + + Horizontal layout + + + + + Report Tools + + + + + Font + + + + + Text alignment + + + + + Items alignment + + + + + Borders + + + + + Report Header + + + + + Report Footer + + + + + Page Header + + + + + Page Footer + + + + + Data + + + + + SubDetail + + + + + SubDetailHeader + + + + + SubDetailFooter + + + + + GroupHeader + + + + + GroupFooter + + + + + File + + + + + Edit + + + + + Object Inspector + + + + + Report structure + + + + + Data Browser + + + + + Script Browser + + + + + Report has been modified ! Do you want save the report ? + + + + + + Report file name + + + + + LimeReport::ReportFooter + + + Report Footer + + + + + LimeReport::ReportHeader + + + Report Header + + + + + LimeReport::ReportRender + + + Error + + + + + Databand "%1" not found + + + + + Wrong using function %1 + + + + + LimeReport::ScriptBrowser + + + NO CATEGORY + + + + + + + Error + + + + + Dialog with name: %1 already exists + + + + + ui file must cointain QDialog instead QWidget or QMainWindow + + + + + wrong file format + + + + + LimeReport::ScriptEngineContext + + + Dialog with name: %1 can`t be created + + + + + LimeReport::SubDetailBand + + + SubDetail + + + + + LimeReport::TextAlignmentEditorWidget + + + Text align left + + + + + + Text align center + + + + + Text align right + + + + + Text align justify + + + + + Text align top + + + + + Text align bottom + + + + + PreviewReportWindow + + + Preview + + + + + View + + + + + Report + + + + + toolBar + + + + + Print + + + + + Ctrl+P + + + + + Zoom In + + + + + Zoom Out + + + + + + Prior Page + + + + + + Next Page + + + + + + Close Preview + + + + + Edit Mode + + + + + + Save to file + + + + + + Показать ошибки + + + + + Font + + + + + Text align + + + + + of %1 + + + + + Report file name + + + + + QObject + + + + Data + + + + + GroupHeader + + + + + GroupFooter + + + + + + Page Footer + + + + + + Page Header + + + + + + Report Footer + + + + + + Report Header + + + + + + SubDetail + + + + + SubDetailHeader + + + + + SubDetailFooter + + + + + alignment + + + + + Barcode Item + + + + + HLayout + + + + + Image Item + + + + + Shape Item + + + + + itemLocation + + + + + Text Item + + + + + Invalid connection! %1 + + + + + Master datasouce "%1" not found! + + + + + Child + + + + + and child + + + + + datasouce "%1" not found! + + + + + Function %1 not found or have wrong arguments + + + + + bool + + + + + QColor + + + + + + datasource + + + + + + field + + + + + enum + + + + + flags + + + + + QFont + + + + + QImage + + + + + int + + + + + qreal + + + + + QRect + + + + + QRectF + + + + + geometry + + + + + mm + + + + + QString + + + + + Wrong file format + + + + + File %1 not opened + + + + + Content string is empty + + + + + Content is empty + + + + + SQLEditDialog + + + Datasource + + + + + Connection + + + + + Datasource Name + + + + + Subdetail + + + + + Master datasource + + + + + Sub query mode + + + + + Filter mode + + + + + SQL + + + + + Child datasource + + + + + Fields map + + + + + + ... + + + + + Cancel + + + + + Ok + + + + + Error + + + + + Datasource Name is empty ! + + + + + SQL is empty ! + + + + + Datasource with name: "%1" already exists ! + + + + + Datasource with name %1 already exist + + + + + ScriptBrowser + + + Form + + + + + Functions + + + + + + + + + + ... + + + + + Dialogs + + + + + Type + + + + + Name + + + + + TextItemEditor + + + Text Item Editor + + + + + Content + + + + + Data + + + + + Functions + + + + + Editor settings + + + + + Editor font + + + + + ... + + + + + Ok + + + + + Cancel + + + + + Esc + + + + + WaitForm + + + Wait + + + + + Please wait ... + + + + diff --git a/src/acollection.cpp b/src/acollection.cpp new file mode 100644 index 0000000..5682a2b --- /dev/null +++ b/src/acollection.cpp @@ -0,0 +1,30 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "acollection.h" diff --git a/src/areportpreviewwidget.h b/src/areportpreviewwidget.h new file mode 100644 index 0000000..d36294e --- /dev/null +++ b/src/areportpreviewwidget.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef AREPORTPREVIEWINTF_H +#define AREPORTPREVIEWINTF_H + +#include +#include + +namespace ArReport{ + +class ReportPreviewWidgetIntf : public QWidget +{ + Q_OBJECT +public: + explicit ReportPreviewWidgetIntf(QWidget *parent=0); +private: + QGraphicsView* m_view; +}; + +} +#endif // AREPORTPREVIEWINTF_H diff --git a/src/bands/lrdataband.cpp b/src/bands/lrdataband.cpp new file mode 100644 index 0000000..3e04c0e --- /dev/null +++ b/src/bands/lrdataband.cpp @@ -0,0 +1,74 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrdataband.h" +#include "lrdesignelementsfactory.h" +#include "lrglobal.h" + +const QString xmlTag ="Data"; + +namespace{ + +LimeReport::BaseDesignIntf * createBand(QObject* owner, LimeReport::BaseDesignIntf* parent){ + return new LimeReport::DataBand(owner,parent); +} +bool registred = LimeReport::DesignElementsFactory::instance().registerCreator( + xmlTag, + LimeReport::ItemAttribs(QObject::tr("Data"),LimeReport::bandTAG), + createBand + ); + +} + +namespace LimeReport { + +DataBand::DataBand(QObject *owner, QGraphicsItem *parent) + : DataBandDesignIntf(LimeReport::BandDesignIntf::Data,xmlTag,owner,parent) { + setBandTypeText(tr("Data")); + setFixedPos(false); + setMarkerColor(bandColor()); +} + +bool DataBand::isUnique() const +{ + return false; +} + +QColor DataBand::bandColor() const +{ + return QColor(Qt::darkGreen); +} + +BaseDesignIntf *DataBand::createSameTypeItem(QObject *owner, QGraphicsItem *parent) +{ + return new DataBand(owner,parent); +} + +} + diff --git a/src/bands/lrdataband.h b/src/bands/lrdataband.h new file mode 100644 index 0000000..cd5b580 --- /dev/null +++ b/src/bands/lrdataband.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRDATABAND_H +#define LRDATABAND_H + +#include "lrbanddesignintf.h" +#include "lrbasedesignintf.h" +#include + +namespace LimeReport{ +class DataBand : public DataBandDesignIntf +{ + Q_OBJECT + Q_PROPERTY(bool keepSubdetailTogether READ tryToKeepTogether WRITE setTryToKeepTogether) + Q_PROPERTY(bool splittable READ isSplittable WRITE setSplittable ) + Q_PROPERTY(bool keepFooterTogether READ keepFooterTogether WRITE setKeepFooterTogether) + Q_PROPERTY(bool sliceLastRow READ sliceLastRow WRITE setSliceLastRow) +public: + DataBand(QObject* owner = 0, QGraphicsItem* parent=0); + bool isUnique() const; + bool isData() const {return true;} +protected: + QColor bandColor() const; +private: + BaseDesignIntf* createSameTypeItem(QObject* owner=0, QGraphicsItem* parent=0); +}; +} +#endif // LRDATABAND_H diff --git a/src/bands/lrgroupbands.cpp b/src/bands/lrgroupbands.cpp new file mode 100644 index 0000000..54b559d --- /dev/null +++ b/src/bands/lrgroupbands.cpp @@ -0,0 +1,156 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrgroupbands.h" +#include "lrglobal.h" +#include "lrdatasourcemanager.h" + + +const QString xmlTagHeader = QLatin1String("GroupHeader"); +const QString xmlTagFooter = QLatin1String("GroupFooter"); + +namespace{ + +LimeReport::BaseDesignIntf* createHeader(QObject* owner, LimeReport::BaseDesignIntf* parent){ + return new LimeReport::GroupBandHeader(owner,parent); +} + +bool registredHeader = LimeReport::DesignElementsFactory::instance().registerCreator( + xmlTagHeader, + LimeReport::ItemAttribs(QObject::tr("GroupHeader"),LimeReport::bandTAG), + createHeader + ); + +LimeReport::BaseDesignIntf * createFooter(QObject* owner, LimeReport::BaseDesignIntf* parent){ + return new LimeReport::GroupBandFooter(owner,parent); +} + +bool registredFooter = LimeReport::DesignElementsFactory::instance().registerCreator( + xmlTagFooter, + LimeReport::ItemAttribs(QObject::tr("GroupFooter"),LimeReport::bandTAG), + createFooter + ); + +} + +namespace LimeReport{ + +GroupBandHeader::GroupBandHeader(QObject *owner, QGraphicsItem *parent) + : BandDesignIntf(BandDesignIntf::GroupHeader, xmlTagHeader, owner,parent), + m_groupFiledName(""), m_groupStarted(false) +{ + setBandTypeText(tr("GroupHeader")); + setFixedPos(false); + setMarkerColor(bandColor()); +} + +bool GroupBandHeader::isUnique() const +{ + return false; +} + +//bool GroupBandHeader::tryToKeepTogether() +//{ +// return m_tryToKeepTogether; +//} + +BaseDesignIntf *GroupBandHeader::createSameTypeItem(QObject *owner, QGraphicsItem *parent) +{ + return new GroupBandHeader(owner, parent); +} + +void GroupBandHeader::startGroup() +{ + m_groupStarted=true; + DataSourceManager* dm = DataSourceManager::instance(); + if ((dm->dataSource(parentBand()->datasourceName()))){ + IDataSource* ds = dm->dataSource(parentBand()->datasourceName()); + if (ds->columnIndexByName(m_groupFiledName)!=-1) + m_groupFieldValue=ds->data(m_groupFiledName); + } +} + +QColor GroupBandHeader::bandColor() const +{ + return QColor(Qt::darkBlue); +} + +bool GroupBandHeader::isNeedToClose() +{ + if (m_groupFieldValue.isNull()) return false; + + DataSourceManager* dm = DataSourceManager::instance(); + if ((dm->dataSource(parentBand()->datasourceName()))){ + IDataSource* ds = dm->dataSource(parentBand()->datasourceName()); + return ds->data(m_groupFiledName)!=m_groupFieldValue; + } + + return false; +} + +bool GroupBandHeader::isStarted() +{ + return !m_groupFieldValue.isNull(); +} + +void GroupBandHeader::closeGroup() +{ + m_groupFieldValue=QVariant(); + m_groupStarted=false; +} + +int GroupBandHeader::index() +{ + return bandIndex(); +} + +GroupBandFooter::GroupBandFooter(QObject *owner, QGraphicsItem *parent) + :BandDesignIntf(BandDesignIntf::GroupFooter, xmlTagFooter, owner,parent) +{ + setBandTypeText(tr("GroupFooter")); + setFixedPos(false); + setMarkerColor(bandColor()); +} + +bool GroupBandFooter::isUnique() const +{ + return false; +} + +QColor GroupBandFooter::bandColor() const +{ + return QColor(Qt::darkBlue); +} + +BaseDesignIntf *GroupBandFooter::createSameTypeItem(QObject *owner, QGraphicsItem *parent) +{ + return new GroupBandFooter(owner,parent); +} + +} //namespace LimeReport diff --git a/src/bands/lrgroupbands.h b/src/bands/lrgroupbands.h new file mode 100644 index 0000000..8520408 --- /dev/null +++ b/src/bands/lrgroupbands.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRGROUPBANDS_H +#define LRGROUPBANDS_H + +#include "lrbanddesignintf.h" +#include "lrdesignelementsfactory.h" + +namespace LimeReport{ + +class GroupBandHeader : public BandDesignIntf, public IGropBand{ + Q_OBJECT + Q_PROPERTY(QString groupFieldName READ groupFieldName WRITE setGroupFieldName) + Q_PROPERTY(bool splittable READ isSplittable WRITE setSplittable ) + Q_PROPERTY(bool keepGroupTogether READ tryToKeepTogether WRITE setTryToKeepTogether) +public: + GroupBandHeader(QObject* owner = 0, QGraphicsItem* parent=0); + virtual bool isUnique() const; + QVariant groupFieldValue(){return m_groupFieldValue;} + void setGroupFieldValue(QVariant value){m_groupFieldValue=value;} + QString groupFieldName(){return m_groupFiledName;} + void setGroupFieldName(QString fieldName){m_groupFiledName=fieldName;} + QColor bandColor() const; +private: + virtual BaseDesignIntf* createSameTypeItem(QObject* owner=0, QGraphicsItem* parent=0); + virtual void startGroup(); + virtual bool isNeedToClose(); + virtual bool isStarted(); + virtual void closeGroup(); + virtual int index(); +private: + QVariant m_groupFieldValue; + QString m_groupFiledName; + bool m_groupStarted; +}; + +class GroupBandFooter : public BandDesignIntf{ + Q_OBJECT +public: + GroupBandFooter(QObject* owner = 0, QGraphicsItem* parent=0); + virtual bool isUnique() const; + QColor bandColor() const; + virtual bool isFooter() const{return true;} +private: + virtual BaseDesignIntf* createSameTypeItem(QObject* owner=0, QGraphicsItem* parent=0); +}; + +} // namespace LimeReport +#endif // LRGROUPBANDS_H diff --git a/src/bands/lrpagefooter.cpp b/src/bands/lrpagefooter.cpp new file mode 100644 index 0000000..addefe7 --- /dev/null +++ b/src/bands/lrpagefooter.cpp @@ -0,0 +1,66 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrpagefooter.h" +#include "lrdesignelementsfactory.h" +#include "lrglobal.h" + +const QString xmlTag ="PageFooter"; + +namespace{ +LimeReport::BaseDesignIntf * createBand(QObject* owner, LimeReport::BaseDesignIntf* parent){ + return new LimeReport::PageFooter(owner,parent); +} + +bool registred = LimeReport::DesignElementsFactory::instance().registerCreator( + xmlTag, + LimeReport::ItemAttribs(QObject::tr("Page Footer"),LimeReport::bandTAG), + createBand + ); +} + +namespace LimeReport{ + +PageFooter::PageFooter(QObject *owner, QGraphicsItem *parent) + : BandDesignIntf(LimeReport::BandDesignIntf::PageFooter,xmlTag,owner,parent) { + setBandTypeText( tr("Page Footer") ); + setMarkerColor(bandColor()); +} + +BaseDesignIntf *PageFooter::createSameTypeItem(QObject *owner, QGraphicsItem *parent) +{ + return new PageFooter(owner,parent); +} + +QColor PageFooter::bandColor() const +{ + return QColor(246,120,12); +} + +} // namespace LimeReport diff --git a/src/bands/lrpagefooter.h b/src/bands/lrpagefooter.h new file mode 100644 index 0000000..8987317 --- /dev/null +++ b/src/bands/lrpagefooter.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRPAGEFOOTER_H +#define LRPAGEFOOTER_H + +#include "lrbanddesignintf.h" +#include "lrbasedesignintf.h" +#include + +namespace LimeReport{ +class PageFooter : public LimeReport::BandDesignIntf +{ + Q_OBJECT +public: + PageFooter(QObject* owner = 0, QGraphicsItem* parent=0); + virtual BaseDesignIntf* createSameTypeItem(QObject* owner=0, QGraphicsItem* parent=0); + virtual bool isFooter() const {return true;} +protected: + QColor bandColor() const; +}; +} + +#endif // LRPAGEFOOTER_H diff --git a/src/bands/lrpageheader.cpp b/src/bands/lrpageheader.cpp new file mode 100644 index 0000000..5b41734 --- /dev/null +++ b/src/bands/lrpageheader.cpp @@ -0,0 +1,70 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrpageheader.h" +#include "lrdesignelementsfactory.h" +#include "lrbanddesignintf.h" +#include "lrbasedesignintf.h" +#include "lrpageitemdesignintf.h" +#include "lrglobal.h" + +const QString xmlTag ="PageHeader"; + +namespace{ + +LimeReport::BaseDesignIntf * createBand(QObject* owner, LimeReport::BaseDesignIntf* parent){ + return new LimeReport::PageHeader(owner,parent); +} + +bool registred = LimeReport::DesignElementsFactory::instance().registerCreator( + xmlTag, + LimeReport::ItemAttribs(QObject::tr("Page Header"),LimeReport::bandTAG), + createBand + ); +} + +namespace LimeReport{ + +PageHeader::PageHeader(QObject* owner, QGraphicsItem *parent) +: BandDesignIntf(LimeReport::BandDesignIntf::PageHeader,xmlTag,owner,parent) { + setBandTypeText(tr("Page Header")); + setMarkerColor(bandColor()); +} + +BaseDesignIntf *PageHeader::createSameTypeItem(QObject *owner, QGraphicsItem *parent) +{ + return new PageHeader(owner,parent); +} + +QColor PageHeader::bandColor() const +{ + return QColor(246,120,12); +} + +} diff --git a/src/bands/lrpageheader.h b/src/bands/lrpageheader.h new file mode 100644 index 0000000..dbbb6f5 --- /dev/null +++ b/src/bands/lrpageheader.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRPAGEHEADER_H +#define LRPAGEHEADER_H + +#include +#include "lrbanddesignintf.h" +#include "lrbasedesignintf.h" + +namespace LimeReport { +class PageHeader : public LimeReport::BandDesignIntf +{ + Q_OBJECT +public: + PageHeader(QObject* owner = 0, QGraphicsItem* parent=0); +protected: + virtual BaseDesignIntf* createSameTypeItem(QObject* owner=0, QGraphicsItem* parent=0); + QColor bandColor() const; +}; +} +#endif // LRPAGEHEADER_H diff --git a/src/bands/lrreportfooter.cpp b/src/bands/lrreportfooter.cpp new file mode 100644 index 0000000..66f6694 --- /dev/null +++ b/src/bands/lrreportfooter.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrreportfooter.h" +#include "lrdesignelementsfactory.h" +#include "lrglobal.h" + +const QString xmlTag ="ReportFooter"; + +namespace{ + +LimeReport::BaseDesignIntf * createBand(QObject* owner, LimeReport::BaseDesignIntf* parent){ + return new LimeReport::ReportFooter(owner,parent); +} +bool registred = LimeReport::DesignElementsFactory::instance().registerCreator( + xmlTag, + LimeReport::ItemAttribs(QObject::tr("Report Footer"),LimeReport::bandTAG), + createBand + ); +} + +namespace LimeReport{ + +ReportFooter::ReportFooter(QObject *owner, QGraphicsItem *parent) + : BandDesignIntf(LimeReport::BandDesignIntf::ReportFooter,xmlTag,owner,parent) { + setBandTypeText(tr("Report Footer")); + setMarkerColor(bandColor()); +} + +BaseDesignIntf *ReportFooter::createSameTypeItem(QObject *owner, QGraphicsItem *parent) +{ + return new ReportFooter(owner,parent); +} + +QColor ReportFooter::bandColor() const +{ + return QColor(152,69,167); +} + +bool ReportFooter::isFooter() const +{ + return true; +} + +} diff --git a/src/bands/lrreportfooter.h b/src/bands/lrreportfooter.h new file mode 100644 index 0000000..140ad1e --- /dev/null +++ b/src/bands/lrreportfooter.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRREPORTFOOTER_H +#define LRREPORTFOOTER_H + +#include +#include "lrbanddesignintf.h" +#include "lrbasedesignintf.h" + +namespace LimeReport{ +class ReportFooter : public BandDesignIntf +{ + Q_OBJECT + Q_PROPERTY(int maxScalePercent READ maxScalePercent WRITE setMaxScalePercent) + Q_PROPERTY(bool splittable READ isSplittable WRITE setSplittable) +public: + ReportFooter(QObject* owner=0, QGraphicsItem* parent=0); + virtual BaseDesignIntf* createSameTypeItem(QObject* owner=0, QGraphicsItem* parent=0); +protected: + QColor bandColor() const; + bool isFooter() const; +}; +} +#endif // LRREPORTFOOTER_H diff --git a/src/bands/lrreportheader.cpp b/src/bands/lrreportheader.cpp new file mode 100644 index 0000000..aa261fc --- /dev/null +++ b/src/bands/lrreportheader.cpp @@ -0,0 +1,64 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrreportheader.h" +#include "lrdesignelementsfactory.h" +#include "lrglobal.h" + +const QString xmlTag ="ReportHeader"; + +namespace{ +LimeReport::BaseDesignIntf * createBand(QObject* owner, LimeReport::BaseDesignIntf* parent){ + return new LimeReport::ReportHeader(owner,parent); +} +bool registred = LimeReport::DesignElementsFactory::instance().registerCreator( + xmlTag, + LimeReport::ItemAttribs(QObject::tr("Report Header"),LimeReport::bandTAG), + createBand + ); +} +namespace LimeReport { + +ReportHeader::ReportHeader(QObject *owner, QGraphicsItem *parent) + : BandDesignIntf(LimeReport::BandDesignIntf::ReportHeader,xmlTag,owner,parent) { + setBandTypeText(tr("Report Header")); + setMarkerColor(bandColor()); +} +BaseDesignIntf *ReportHeader::createSameTypeItem(QObject *owner, QGraphicsItem *parent) +{ + return new ReportHeader(owner,parent); +} + +QColor ReportHeader::bandColor() const +{ + return QColor(152,69,167); +} + +} + diff --git a/src/bands/lrreportheader.h b/src/bands/lrreportheader.h new file mode 100644 index 0000000..bc70667 --- /dev/null +++ b/src/bands/lrreportheader.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRREPORTHEADER_H +#define LRREPORTHEADER_H + +#include +#include "lrbanddesignintf.h" +#include "lrbasedesignintf.h" + +namespace LimeReport{ +class ReportHeader : public LimeReport::BandDesignIntf +{ + Q_OBJECT + Q_PROPERTY(bool splittable READ isSplittable WRITE setSplittable ) +public: + ReportHeader(QObject* owner = 0, QGraphicsItem *parent=0); + virtual BaseDesignIntf* createSameTypeItem(QObject* owner=0, QGraphicsItem* parent=0); +protected: + QColor bandColor() const; +}; +} +#endif // LRREPORTHEADER_H diff --git a/src/bands/lrsubdetailband.cpp b/src/bands/lrsubdetailband.cpp new file mode 100644 index 0000000..d1844fe --- /dev/null +++ b/src/bands/lrsubdetailband.cpp @@ -0,0 +1,153 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrsubdetailband.h" +#include "lrdesignelementsfactory.h" +#include "lrglobal.h" + + +const QString xmlTagBand = QLatin1String("SubDetail"); +const QString xmlTagHeader = QLatin1String("SubDetailHeader"); +const QString xmlTagFooter = QLatin1String("SubDetailFooter"); +const QColor BAND_COLOR = Qt::red; + +namespace{ + +LimeReport::BaseDesignIntf * createBand(QObject* owner, LimeReport::BaseDesignIntf* parent){ + return new LimeReport::SubDetailBand(owner,parent); +} + +bool registred = LimeReport::DesignElementsFactory::instance().registerCreator( + xmlTagBand, + LimeReport::ItemAttribs(QObject::tr("SubDetail"),LimeReport::bandTAG), + createBand + ); + +LimeReport::BaseDesignIntf * createHeader(QObject* owner, LimeReport::BaseDesignIntf* parent){ + return new LimeReport::SubDetailHeaderBand(owner,parent); +} + +bool registredHeader = LimeReport::DesignElementsFactory::instance().registerCreator( + xmlTagHeader, + LimeReport::ItemAttribs(QObject::tr("SubDetailHeader"),LimeReport::bandTAG), + createHeader + ); + +LimeReport::BaseDesignIntf * createFooter(QObject* owner, LimeReport::BaseDesignIntf* parent){ + return new LimeReport::SubDetailFooterBand(owner,parent); +} + +bool registredFooter = LimeReport::DesignElementsFactory::instance().registerCreator( + xmlTagFooter, + LimeReport::ItemAttribs(QObject::tr("SubDetailFooter"),LimeReport::bandTAG), + createFooter + ); + +} // namespace + +namespace LimeReport{ + +//SubDetailBand + +SubDetailBand::SubDetailBand(QObject *owner, QGraphicsItem *parent) + : DataBandDesignIntf(BandDesignIntf::SubDetailBand, xmlTagBand, owner,parent) +{ + setBandTypeText(tr("SubDetail")); + setFixedPos(false); + setMarkerColor(bandColor()); +} + +bool SubDetailBand::isHasHeader() const +{ + return isConnectedToBand(BandDesignIntf::SubDetailHeader); +} + +bool SubDetailBand::isHasFooter() const +{ + return isConnectedToBand(BandDesignIntf::SubDetailFooter); +} + +BaseDesignIntf *SubDetailBand::createSameTypeItem(QObject *owner, QGraphicsItem *parent) +{ + return new SubDetailBand(owner,parent); +} + +QColor SubDetailBand::bandColor() const +{ + return BAND_COLOR; +} + +//SubDetailHeaderBand + +SubDetailHeaderBand::SubDetailHeaderBand(QObject *owner, QGraphicsItem *parent) + :BandDesignIntf(BandDesignIntf::SubDetailHeader,xmlTagHeader,owner,parent), m_printAlways(false) +{ + setMarkerColor(bandColor()); +} + +bool SubDetailHeaderBand::isUnique() const +{ + return false; +} + +QColor SubDetailHeaderBand::bandColor() const +{ + return BAND_COLOR; +} + +BaseDesignIntf *SubDetailHeaderBand::createSameTypeItem(QObject *owner, QGraphicsItem *parent) +{ + return new SubDetailHeaderBand(owner,parent); +} + +//SubDetailFooterBand + +SubDetailFooterBand::SubDetailFooterBand(QObject *owner, QGraphicsItem *parent) + : BandDesignIntf(BandDesignIntf::SubDetailFooter,xmlTagFooter,owner,parent), m_printAlways(false) +{ + setMarkerColor(bandColor()); +} + +bool SubDetailFooterBand::isUnique() const +{ + return false; +} + +QColor SubDetailFooterBand::bandColor() const +{ + return BAND_COLOR; +} + +BaseDesignIntf *SubDetailFooterBand::createSameTypeItem(QObject *owner, QGraphicsItem *parent) +{ + return new SubDetailFooterBand(owner,parent); +} + + +} diff --git a/src/bands/lrsubdetailband.h b/src/bands/lrsubdetailband.h new file mode 100644 index 0000000..3bfe1b4 --- /dev/null +++ b/src/bands/lrsubdetailband.h @@ -0,0 +1,89 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRSUBDETAILBAND_H +#define LRSUBDETAILBAND_H + +#include "lrbanddesignintf.h" +#include "lrbasedesignintf.h" + +namespace LimeReport{ + +class SubDetailBand : public DataBandDesignIntf +{ + Q_OBJECT + Q_PROPERTY(bool splittable READ isSplittable WRITE setSplittable) +public: + SubDetailBand(QObject* owner = 0, QGraphicsItem* parent=0); + bool isUnique() const {return false;} + bool isHasHeader() const; + bool isHasFooter() const; +private: + virtual BaseDesignIntf* createSameTypeItem(QObject* owner=0, QGraphicsItem* parent=0); +protected: + virtual QColor bandColor() const; +}; + +class SubDetailHeaderBand : public BandDesignIntf +{ + Q_OBJECT + Q_PROPERTY(bool printAlways READ printAlways() WRITE setPrintAlways()) +public: + SubDetailHeaderBand(QObject* owner = 0, QGraphicsItem* parent=0); + virtual bool isUnique() const; + void setPrintAlways(bool value){m_printAlways=value;} + bool printAlways(){return m_printAlways;} +protected: + virtual QColor bandColor() const; +private: + virtual BaseDesignIntf* createSameTypeItem(QObject* owner=0, QGraphicsItem* parent=0); +private: + bool m_printAlways; +}; + +class SubDetailFooterBand : public BandDesignIntf +{ + Q_OBJECT + Q_PROPERTY(bool printAlways READ printAlways() WRITE setPrintAlways()) +public: + SubDetailFooterBand(QObject* owner = 0, QGraphicsItem* parent=0); + void setPrintAlways(bool value){m_printAlways=value;} + bool printAlways(){return m_printAlways;} + virtual bool isUnique() const; + virtual bool isFooter() const{return true;} +protected: + virtual QColor bandColor() const; +private: + virtual BaseDesignIntf* createSameTypeItem(QObject* owner=0, QGraphicsItem* parent=0); +private: + bool m_printAlways; +}; + +} +#endif // LRSUBDETAILBAND_H diff --git a/src/base/lrattribsabstractfactory.h b/src/base/lrattribsabstractfactory.h new file mode 100644 index 0000000..d760aa5 --- /dev/null +++ b/src/base/lrattribsabstractfactory.h @@ -0,0 +1,82 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRATTRIBABSTRACTFACTORY_H +#define LRATTRIBABSTRACTFACTORY_H + +#include "lrsingleton.h" +#include "lrglobal.h" +#include +#include +#include + +namespace LimeReport{ + +template +< + typename AbstractProduct, + typename IdentifierType, + typename ProductCreator, + typename Attribs +> +class AttribsAbstractFactory + : public Singleton< AttribsAbstractFactory< AbstractProduct,IdentifierType,ProductCreator,Attribs > > +{ +private: + typedef QMap FactoryMap; + typedef QMap AliasMap; + friend class Singleton< AttribsAbstractFactory< AbstractProduct,IdentifierType,ProductCreator,Attribs > >; +public: + bool registerCreator(const IdentifierType& id, Attribs attribs, ProductCreator creator){ + return (m_factoryMap.insert(id,creator).value()==creator)&& + (m_attribsMap.insert(id,attribs).value()==attribs); + } + bool unregisterCreator(const IdentifierType& id){ + return (m_factoryMap.remove(id)==1)&&(m_attribsMap.remove(id)==1); + } + ProductCreator objectCreator(const IdentifierType& id){ + if (m_factoryMap.contains(id)){ + return m_factoryMap[id]; + } else return 0; + } + QString attribs(const IdentifierType& id){ + if (m_attribsMap.contains(id)){ + return m_attribsMap.value(id); + } else return ""; + } + const FactoryMap& map(){return m_factoryMap;} + const AliasMap& attribsMap(){return m_attribsMap;} + int mapElementCount(){return m_factoryMap.count();} +private: + FactoryMap m_factoryMap; + AliasMap m_attribsMap; +}; + +} +#endif // LRATTRIBABSTRACTFACTORY_H diff --git a/src/base/lrsimpleabstractfactory.h b/src/base/lrsimpleabstractfactory.h new file mode 100644 index 0000000..3722a8b --- /dev/null +++ b/src/base/lrsimpleabstractfactory.h @@ -0,0 +1,103 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRSIMPLEABSTRACTFACTORY_H +#define LRSIMPLEABSTRACTFACTORY_H + +#include "lrsingleton.h" +#include "lrglobal.h" +#include +#include +#include +#include +namespace LimeReport{ + +template +< + typename AbstractProduct, + typename IdentifierType, + typename ProductCreator +> +class SimpleAbstractFactory + : public Singleton< SimpleAbstractFactory< AbstractProduct,IdentifierType,ProductCreator > > +{ +private: + typedef QHash FactoryMap; + friend class Singleton< SimpleAbstractFactory< AbstractProduct,IdentifierType,ProductCreator > >; +public: + bool registerCreator(const IdentifierType& id, ProductCreator creator){ + return (m_factoryMap.insert(id,creator).value()==creator); + } + bool unregisterCreator(const IdentifierType& id){ + return (m_factoryMap.remove(id)==1); + } + ProductCreator objectCreator(const IdentifierType& id){ + if (m_factoryMap.contains(id)){ + return m_factoryMap[id]; + } else { + return 0; + } + } + const FactoryMap& map(){return m_factoryMap;} + int mapElementCount(){return m_factoryMap.count();} +private: + FactoryMap m_factoryMap; +}; + +template +< + typename AbstractProduct, + typename IdentifierType, + typename ProductCreator, + typename Attribs +> +class AttribAbstractFactory : public SimpleAbstractFactory< AbstractProduct,IdentifierType,ProductCreator >{ + typedef SimpleAbstractFactory< AbstractProduct,IdentifierType,ProductCreator > SimpleFactory; + typedef QMap AliasMap; + friend class Singleton >; +public : + bool registerCreator(const IdentifierType &id, Attribs attribs, ProductCreator creator){ + return SimpleFactory::registerCreator(id,creator) && (m_attribsMap.insert(id,attribs).value()==attribs); + } + bool unregisterCreator(const IdentifierType &id){ + return SimpleFactory::unregisterCreator(id)&&(m_attribsMap.remove(id)==1); + } + QString attribs(const IdentifierType& id){ + if (m_attribsMap.contains(id)){ + return m_attribsMap.value(id); + } else return ""; + } + const AliasMap& attribsMap(){return m_attribsMap;} +private: + AliasMap m_attribsMap; +}; + +} + +#endif //LRSIMPLEABSTRACTFACTORY_H diff --git a/src/base/lrsingleton.h b/src/base/lrsingleton.h new file mode 100644 index 0000000..f011872 --- /dev/null +++ b/src/base/lrsingleton.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRSINGLETON_H +#define LRSINGLETON_H + +#include + +namespace LimeReport{ + +template +class Singleton +{ +public: + static T& instance(){ + if (0==inst){ + inst = new T(); + ::atexit( destroy ); + } else {}; + return *inst; + } +private: + static T* inst; +private: + static void destroy() { + delete inst; + } +}; + +template +T* Singleton< T >::inst =0; +} +#endif // LRSINGLETON_H diff --git a/src/databrowser/images/add.png b/src/databrowser/images/add.png new file mode 100644 index 0000000..7ab3357 Binary files /dev/null and b/src/databrowser/images/add.png differ diff --git a/src/databrowser/images/check.png b/src/databrowser/images/check.png new file mode 100644 index 0000000..3bde53b Binary files /dev/null and b/src/databrowser/images/check.png differ diff --git a/src/databrowser/images/check_circle.png b/src/databrowser/images/check_circle.png new file mode 100644 index 0000000..7fe467b Binary files /dev/null and b/src/databrowser/images/check_circle.png differ diff --git a/src/databrowser/images/cursor-small.png b/src/databrowser/images/cursor-small.png new file mode 100644 index 0000000..7643a54 Binary files /dev/null and b/src/databrowser/images/cursor-small.png differ diff --git a/src/databrowser/images/data.png b/src/databrowser/images/data.png new file mode 100644 index 0000000..65007f7 Binary files /dev/null and b/src/databrowser/images/data.png differ diff --git a/src/databrowser/images/data1.png b/src/databrowser/images/data1.png new file mode 100644 index 0000000..cf5baca Binary files /dev/null and b/src/databrowser/images/data1.png differ diff --git a/src/databrowser/images/data_add.png b/src/databrowser/images/data_add.png new file mode 100644 index 0000000..4525abc Binary files /dev/null and b/src/databrowser/images/data_add.png differ diff --git a/src/databrowser/images/data_add1.png b/src/databrowser/images/data_add1.png new file mode 100644 index 0000000..e7c035d Binary files /dev/null and b/src/databrowser/images/data_add1.png differ diff --git a/src/databrowser/images/data_delete.png b/src/databrowser/images/data_delete.png new file mode 100644 index 0000000..338a456 Binary files /dev/null and b/src/databrowser/images/data_delete.png differ diff --git a/src/databrowser/images/data_delete1.png b/src/databrowser/images/data_delete1.png new file mode 100644 index 0000000..f84b18c Binary files /dev/null and b/src/databrowser/images/data_delete1.png differ diff --git a/src/databrowser/images/data_edit.png b/src/databrowser/images/data_edit.png new file mode 100644 index 0000000..9a51969 Binary files /dev/null and b/src/databrowser/images/data_edit.png differ diff --git a/src/databrowser/images/data_edit1.png b/src/databrowser/images/data_edit1.png new file mode 100644 index 0000000..21f64c0 Binary files /dev/null and b/src/databrowser/images/data_edit1.png differ diff --git a/src/databrowser/images/database_connect.png b/src/databrowser/images/database_connect.png new file mode 100644 index 0000000..0628985 Binary files /dev/null and b/src/databrowser/images/database_connect.png differ diff --git a/src/databrowser/images/database_connected.png b/src/databrowser/images/database_connected.png new file mode 100644 index 0000000..a9afa58 Binary files /dev/null and b/src/databrowser/images/database_connected.png differ diff --git a/src/databrowser/images/database_connected2.png b/src/databrowser/images/database_connected2.png new file mode 100644 index 0000000..d5e1022 Binary files /dev/null and b/src/databrowser/images/database_connected2.png differ diff --git a/src/databrowser/images/database_connected3.png b/src/databrowser/images/database_connected3.png new file mode 100644 index 0000000..af832d4 Binary files /dev/null and b/src/databrowser/images/database_connected3.png differ diff --git a/src/databrowser/images/database_disconnect.png b/src/databrowser/images/database_disconnect.png new file mode 100644 index 0000000..20ff200 Binary files /dev/null and b/src/databrowser/images/database_disconnect.png differ diff --git a/src/databrowser/images/edit_table.png b/src/databrowser/images/edit_table.png new file mode 100644 index 0000000..4596124 Binary files /dev/null and b/src/databrowser/images/edit_table.png differ diff --git a/src/databrowser/images/error.png b/src/databrowser/images/error.png new file mode 100644 index 0000000..9cee887 Binary files /dev/null and b/src/databrowser/images/error.png differ diff --git a/src/databrowser/images/error_message.png b/src/databrowser/images/error_message.png new file mode 100644 index 0000000..6c80de1 Binary files /dev/null and b/src/databrowser/images/error_message.png differ diff --git a/src/databrowser/images/error_message_2.png b/src/databrowser/images/error_message_2.png new file mode 100644 index 0000000..015d23c Binary files /dev/null and b/src/databrowser/images/error_message_2.png differ diff --git a/src/databrowser/images/field.png b/src/databrowser/images/field.png new file mode 100644 index 0000000..da58806 Binary files /dev/null and b/src/databrowser/images/field.png differ diff --git a/src/databrowser/images/greenled.png b/src/databrowser/images/greenled.png new file mode 100644 index 0000000..0e10788 Binary files /dev/null and b/src/databrowser/images/greenled.png differ diff --git a/src/databrowser/images/note_edit.png b/src/databrowser/images/note_edit.png new file mode 100644 index 0000000..c199961 Binary files /dev/null and b/src/databrowser/images/note_edit.png differ diff --git a/src/databrowser/images/plug-connect.png b/src/databrowser/images/plug-connect.png new file mode 100644 index 0000000..7af930e Binary files /dev/null and b/src/databrowser/images/plug-connect.png differ diff --git a/src/databrowser/images/plug-disconnect-slash.png b/src/databrowser/images/plug-disconnect-slash.png new file mode 100644 index 0000000..6010982 Binary files /dev/null and b/src/databrowser/images/plug-disconnect-slash.png differ diff --git a/src/databrowser/images/plug-disconnect.png b/src/databrowser/images/plug-disconnect.png new file mode 100644 index 0000000..ce71853 Binary files /dev/null and b/src/databrowser/images/plug-disconnect.png differ diff --git a/src/databrowser/images/pointer.png b/src/databrowser/images/pointer.png new file mode 100644 index 0000000..ea87a66 Binary files /dev/null and b/src/databrowser/images/pointer.png differ diff --git a/src/databrowser/images/remove.png b/src/databrowser/images/remove.png new file mode 100644 index 0000000..afbb0ee Binary files /dev/null and b/src/databrowser/images/remove.png differ diff --git a/src/databrowser/images/row.png b/src/databrowser/images/row.png new file mode 100644 index 0000000..b1971ba Binary files /dev/null and b/src/databrowser/images/row.png differ diff --git a/src/databrowser/images/table.png b/src/databrowser/images/table.png new file mode 100644 index 0000000..30916b5 Binary files /dev/null and b/src/databrowser/images/table.png differ diff --git a/src/databrowser/images/table_add.png b/src/databrowser/images/table_add.png new file mode 100644 index 0000000..c10db3e Binary files /dev/null and b/src/databrowser/images/table_add.png differ diff --git a/src/databrowser/images/table_db.png b/src/databrowser/images/table_db.png new file mode 100644 index 0000000..fa41658 Binary files /dev/null and b/src/databrowser/images/table_db.png differ diff --git a/src/databrowser/images/table_delete.png b/src/databrowser/images/table_delete.png new file mode 100644 index 0000000..e2655d9 Binary files /dev/null and b/src/databrowser/images/table_delete.png differ diff --git a/src/databrowser/images/table_delete1.png b/src/databrowser/images/table_delete1.png new file mode 100644 index 0000000..1dbc388 Binary files /dev/null and b/src/databrowser/images/table_delete1.png differ diff --git a/src/databrowser/images/table_edit.png b/src/databrowser/images/table_edit.png new file mode 100644 index 0000000..1d348b1 Binary files /dev/null and b/src/databrowser/images/table_edit.png differ diff --git a/src/databrowser/images/table_error.png b/src/databrowser/images/table_error.png new file mode 100644 index 0000000..bbf8909 Binary files /dev/null and b/src/databrowser/images/table_error.png differ diff --git a/src/databrowser/images/table_error1.png b/src/databrowser/images/table_error1.png new file mode 100644 index 0000000..3976928 Binary files /dev/null and b/src/databrowser/images/table_error1.png differ diff --git a/src/databrowser/images/table_good.png b/src/databrowser/images/table_good.png new file mode 100644 index 0000000..3883f46 Binary files /dev/null and b/src/databrowser/images/table_good.png differ diff --git a/src/databrowser/images/table_good1.png b/src/databrowser/images/table_good1.png new file mode 100644 index 0000000..d175d33 Binary files /dev/null and b/src/databrowser/images/table_good1.png differ diff --git a/src/databrowser/images/table_view.png b/src/databrowser/images/table_view.png new file mode 100644 index 0000000..592de5d Binary files /dev/null and b/src/databrowser/images/table_view.png differ diff --git a/src/databrowser/images/table_view1.png b/src/databrowser/images/table_view1.png new file mode 100644 index 0000000..8f8c83c Binary files /dev/null and b/src/databrowser/images/table_view1.png differ diff --git a/src/databrowser/images/value.png b/src/databrowser/images/value.png new file mode 100644 index 0000000..6c4b820 Binary files /dev/null and b/src/databrowser/images/value.png differ diff --git a/src/databrowser/images/value1.png b/src/databrowser/images/value1.png new file mode 100644 index 0000000..c255914 Binary files /dev/null and b/src/databrowser/images/value1.png differ diff --git a/src/databrowser/images/value_add.png b/src/databrowser/images/value_add.png new file mode 100644 index 0000000..5261b39 Binary files /dev/null and b/src/databrowser/images/value_add.png differ diff --git a/src/databrowser/images/value_add1.png b/src/databrowser/images/value_add1.png new file mode 100644 index 0000000..fd3ecce Binary files /dev/null and b/src/databrowser/images/value_add1.png differ diff --git a/src/databrowser/images/value_add2.png b/src/databrowser/images/value_add2.png new file mode 100644 index 0000000..5e6b9cc Binary files /dev/null and b/src/databrowser/images/value_add2.png differ diff --git a/src/databrowser/images/value_delete.png b/src/databrowser/images/value_delete.png new file mode 100644 index 0000000..7038ead Binary files /dev/null and b/src/databrowser/images/value_delete.png differ diff --git a/src/databrowser/images/value_delete1.png b/src/databrowser/images/value_delete1.png new file mode 100644 index 0000000..832b392 Binary files /dev/null and b/src/databrowser/images/value_delete1.png differ diff --git a/src/databrowser/images/value_edit.png b/src/databrowser/images/value_edit.png new file mode 100644 index 0000000..1464941 Binary files /dev/null and b/src/databrowser/images/value_edit.png differ diff --git a/src/databrowser/images/value_edit1.png b/src/databrowser/images/value_edit1.png new file mode 100644 index 0000000..70d340a Binary files /dev/null and b/src/databrowser/images/value_edit1.png differ diff --git a/src/databrowser/images/value_edit2.png b/src/databrowser/images/value_edit2.png new file mode 100644 index 0000000..2cd4d7c Binary files /dev/null and b/src/databrowser/images/value_edit2.png differ diff --git a/src/databrowser/lrconnectiondialog.cpp b/src/databrowser/lrconnectiondialog.cpp new file mode 100644 index 0000000..1676c82 --- /dev/null +++ b/src/databrowser/lrconnectiondialog.cpp @@ -0,0 +1,149 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrconnectiondialog.h" +#include "ui_lrconnectiondialog.h" +#include "lrglobal.h" +#include +#include +#include +#include +#include +#include + +ConnectionDialog::ConnectionDialog(LimeReport::IConnectionController *conControl, LimeReport::ConnectionDesc* connectionDesc, QWidget *parent) : + QDialog(parent), + ui(new Ui::ConnectionDialog),m_connection(connectionDesc),m_controller(conControl) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose,true); + m_changeMode=m_connection!=0; +} + +ConnectionDialog::~ConnectionDialog() +{ + delete ui; +} + +void ConnectionDialog::init() +{ + ui->cbbDrivers->addItems(QSqlDatabase::drivers()); +} + +void ConnectionDialog::showEvent(QShowEvent *) +{ + connectionToUI(); +} + +void ConnectionDialog::slotAccept() +{ + try { + checkFieldsFill(); + if (ui->cbAutoConnect->isChecked()) checkConnection(); + if (!m_connection){ + m_controller->addConnectionDesc(uiToConnection()); + } else { + m_controller->changeConnectionDesc(uiToConnection()); + } + close(); + } + catch(LimeReport::ReportError &exception){ + QMessageBox::critical(this,tr("Error"),exception.what()); + } +} + +void ConnectionDialog::slotCheckConnection() +{ + try{ + checkConnection(); + QMessageBox::information(this,tr("Connection"),tr("Connection succsesfully established!")); + } catch(LimeReport::ReportError &exception) { + QMessageBox::critical(this,tr("Error"),exception.what()); + } +} + +void ConnectionDialog::checkFieldsFill() +{ + if (ui->leConnectionName->text().isEmpty()){throw LimeReport::ReportError(tr("Connection Name is empty"));} + if (!m_changeMode&&QSqlDatabase::connectionNames().contains(ui->leConnectionName->text())) { + throw LimeReport::ReportError(tr("Connection with name ")+ui->leConnectionName->text()+tr(" already exists ")); + } +} + +bool ConnectionDialog::checkConnection() +{ + bool connectionEstablished = false; + QString lastError; + { + QSqlDatabase db = QSqlDatabase::addDatabase(ui->cbbDrivers->currentText(),ui->leConnectionName->text()+"_check"); + db.setHostName(ui->leServerName->text()); + db.setUserName(ui->leUserName->text()); + db.setDatabaseName(ui->leDataBase->text()); + db.setPassword(ui->lePassword->text()); + connectionEstablished = db.open(); + if (!db.open()) { + lastError=db.lastError().text(); + } + } + QSqlDatabase::removeDatabase(ui->leConnectionName->text()+"_check"); + if (!connectionEstablished) throw LimeReport::ReportError(lastError); + return true; +} + +LimeReport::ConnectionDesc *ConnectionDialog::uiToConnection() +{ + if (!m_connection) m_connection = new LimeReport::ConnectionDesc(); + m_connection->setName(ui->leConnectionName->text()); + m_connection->setHost(ui->leServerName->text()); + m_connection->setDriver(ui->cbbDrivers->currentText()); + m_connection->setUserName(ui->leUserName->text()); + m_connection->setPassword(ui->lePassword->text()); + m_connection->setDatabaseName(ui->leDataBase->text()); + m_connection->setAutoconnect(ui->cbAutoConnect->isChecked()); + return m_connection; +} + +void ConnectionDialog::connectionToUI() +{ + init(); + if (!m_connection) return; + ui->leConnectionName->setText(m_connection->name()); + ui->leDataBase->setText(m_connection->databaseName()); + ui->leServerName->setText(m_connection->host()); + ui->leUserName->setText(m_connection->userName()); + ui->lePassword->setText(m_connection->password()); + ui->cbbDrivers->setCurrentIndex(ui->cbbDrivers->findText(m_connection->driver())); + ui->cbAutoConnect->setChecked(m_connection->autoconnect()); +} + + +void ConnectionDialog::on_toolButton_clicked() +{ + ui->leDataBase->setText(QFileDialog::getOpenFileName()); +} diff --git a/src/databrowser/lrconnectiondialog.h b/src/databrowser/lrconnectiondialog.h new file mode 100644 index 0000000..7d22dd9 --- /dev/null +++ b/src/databrowser/lrconnectiondialog.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRCONNECTIONDIALOG_H +#define LRCONNECTIONDIALOG_H + +#include +#include "lrdatadesignintf.h" + +namespace Ui { + class ConnectionDialog; +} + +class ConnectionDialog : public QDialog +{ + Q_OBJECT +public: + explicit ConnectionDialog(LimeReport::IConnectionController* conControl, LimeReport::ConnectionDesc* connectionDesc=0, QWidget *parent = 0); + ~ConnectionDialog(); +protected: + void showEvent(QShowEvent *); + void init(); + void checkFieldsFill(); + bool checkConnection(); + LimeReport::ConnectionDesc* uiToConnection(); + void connectionToUI(); +signals: + void conectionRegistred(LimeReport::ConnectionDesc* connectionDesc); +private slots: + void slotAccept(); + void slotCheckConnection(); + void on_toolButton_clicked(); + +private: + Ui::ConnectionDialog *ui; + LimeReport::ConnectionDesc* m_connection; + bool m_changeMode; + LimeReport::IConnectionController* m_controller; +}; + +#endif // LRCONNECTIONDIALOG_H diff --git a/src/databrowser/lrconnectiondialog.ui b/src/databrowser/lrconnectiondialog.ui new file mode 100644 index 0000000..b292cf5 --- /dev/null +++ b/src/databrowser/lrconnectiondialog.ui @@ -0,0 +1,249 @@ + + + ConnectionDialog + + + + 0 + 0 + 420 + 294 + + + + Connection + + + + :/databrowser/images/database_disconnected:/databrowser/images/database_disconnected + + + + + + + + Connection Name + + + + + + + + + + + + + + + + + + Driver + + + + + + + + + + Server + + + + + + + + + + + + + + User + + + + + + + + + + + + + + Password + + + + + + + + + + QLineEdit::Password + + + + + + + Database + + + + + + + 2 + + + + + + + + + + + + ... + + + + + + + + + + + Auto connect + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + + + Check connection + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Cancel + + + false + + + + + + + Ok + + + + + + + + + + + + + pbOk + clicked() + ConnectionDialog + slotAccept() + + + 388 + 266 + + + 376 + 215 + + + + + pbCancel + clicked() + ConnectionDialog + reject() + + + 268 + 263 + + + 255 + 225 + + + + + pbCheckConnection + clicked() + ConnectionDialog + slotCheckConnection() + + + 28 + 271 + + + 36 + 224 + + + + + + slotAccept() + slotCheckConnection() + + diff --git a/src/databrowser/lrdatabrowser.cpp b/src/databrowser/lrdatabrowser.cpp new file mode 100644 index 0000000..4bd07cb --- /dev/null +++ b/src/databrowser/lrdatabrowser.cpp @@ -0,0 +1,705 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ui_lrdatabrowser.h" + +#include "lrdatabrowser.h" +#include "lrsqleditdialog.h" +#include "lrconnectiondialog.h" +#include "lrreportengine_p.h" +#include "lrvariabledialog.h" +#include "lrdatabrowsertree.h" + +namespace LimeReport{ + +DataBrowser::DataBrowser(QWidget *parent) : + QWidget(parent), + ui(new Ui::DataBrowser), m_report(0), m_closingWindows(false), m_settings(0), m_ownedSettings(false) +{ + ui->setupUi(this); + connect(ui->addConnection,SIGNAL(clicked()),this,SLOT(slotAddConnection())); + connect(ui->deleteConection,SIGNAL(clicked()),this,SLOT(slotDeleteConnection())); + connect(ui->addDataSource,SIGNAL(clicked()),this,SLOT(slotAddDataSource())); + connect(ui->viewDataSource,SIGNAL(clicked()),this,SLOT(slotViewDatasource())); + connect(ui->editDataSource,SIGNAL(clicked()),this,SLOT(slotEditDatasource())); + connect(ui->deleteDataSource,SIGNAL(clicked()),this,SLOT(slotDeleteDatasource())); + connect(ui->changeConnection,SIGNAL(clicked()),this,SLOT(slotChangeConnection())); + connect(ui->pbConnect,SIGNAL(clicked()),this,SLOT(slotChangeConnectionState())); + + ui->dataTree->setHeaderLabel(tr("Datasources")); + ui->pbConnect->setEnabled(false); +} + +DataBrowser::~DataBrowser() +{ + delete ui; + if (m_settings && m_ownedSettings) + delete m_settings; +} +QSize DataBrowser::sizeHint() const +{ + return QSize(100,200); +} + +void DataBrowser::slotAddConnection() +{ + ConnectionDialog *connectionEdit = new ConnectionDialog(this,0,this); + connectionEdit->setAttribute(Qt::WA_DeleteOnClose,true); +#if defined(WIN32) || defined(WIN64) + connectionEdit->setWindowModality(Qt::ApplicationModal); +#else + connectionEdit->setWindowModality(Qt::WindowModal); +#endif + //connect(connectionEdit,SIGNAL(finished(int)),this,SLOT(slotConnectionEditFinished(int))); + //connect(connectionEdit,SIGNAL(conectionRegistred(QString)),this,SLOT(slotConnectionRegistred(QString))); + connectionEdit->exec(); +} + +void DataBrowser::slotSQLEditingFinished(SQLEditResult result) +{ + if (result.dialogMode==SQLEditDialog::AddMode) { + switch (result.resultMode) { + case SQLEditResult::Query: + addQuery(result); + break; + case SQLEditResult::SubQuery: + addSubQuery(result); + break; + case SQLEditResult::SubProxy: + addProxy(result); + default: + break; + } + } else { + switch(result.resultMode){ + case SQLEditResult::Query: + changeQuery(result); + break; + case SQLEditResult::SubQuery: + changeSubQuery(result); + break; + case SQLEditResult::SubProxy: + changeProxy(result); + } + } + + updateDataTree(); +} + +void DataBrowser::slotDeleteConnection() +{ + if (!getConnectionName().isEmpty()){ + if ( + QMessageBox::critical( + this, + tr("Attention"), + tr("Do you really want delete \"%1\" connection ?").arg(getConnectionName()), + QMessageBox::Ok|QMessageBox::No, + QMessageBox::No + )==QMessageBox::Ok + ){ + m_report->dataManager()->removeConnection(getConnectionName()); + updateDataTree(); + } + } +} + +void DataBrowser::slotAddDataSource() +{ + SQLEditDialog *sqlEdit = new SQLEditDialog(this,m_report->dataManager(),SQLEditDialog::AddMode); + sqlEdit->setAttribute(Qt::WA_DeleteOnClose,true); +#if defined(WIN64) || defined(WIN32) + sqlEdit->setWindowModality(Qt::ApplicationModal); +#else + sqlEdit->setWindowModality(Qt::WindowModal); +#endif + sqlEdit->setSettings(settings()); + sqlEdit->setDataSources(m_report->dataManager()); + sqlEdit->setDefaultConnection(getConnectionName()); + connect(sqlEdit,SIGNAL(signalSqlEditingFinished(SQLEditResult)),this,SLOT(slotSQLEditingFinished(SQLEditResult))); + sqlEdit->exec(); +} + +void DataBrowser::updateDataTree() +{ + QString selectedText = ""; + int selectedType = 0; + + if (ui->dataTree->selectedItems().count()==1){ + selectedType = ui->dataTree->selectedItems().at(0)->type(); + selectedText = ui->dataTree->selectedItems().at(0)->text(0); + } + + initConnections(); + + foreach(QString dataSourceName, m_report->datasourcesNames()){ + + QTreeWidgetItem *item=new QTreeWidgetItem(QStringList(dataSourceName),DataBrowserTree::Table); + QTreeWidgetItem *parentItem = findByNameAndType(m_report->dataManager()->connectionName(dataSourceName),DataBrowserTree::Connection); + if (parentItem){ + parentItem->addChild(item); + if (!parentItem->isExpanded()) ui->dataTree->expandItem(parentItem); + } else { + ui->dataTree->addTopLevelItem(item); + } + + try{ + IDataSource* datasource = m_report->dataManager()->dataSource(dataSourceName); + if (datasource){ + fillFields(item,datasource); + if (!datasource->isInvalid()) + item->setIcon(0,QIcon(":/databrowser/images/table_good")); + else + item->setIcon(0,QIcon(":/databrowser/images/table_error")); + + } else item->setIcon(0,QIcon(":/databrowser/images/table_error")); + + } catch(ReportError& exception) { + item->setIcon(0,QIcon(":/databrowser/images/table_error")); + //qDebug()<setSelected(true); + ui->dataTree->setCurrentItem(selectedItem); + } +} + +void DataBrowser::updateVariablesTree() +{ + ui->variablesTree->clear(); + QTreeWidgetItem *userVariables =new QTreeWidgetItem(QStringList(tr("User variables")),DataBrowserTree::Category); + userVariables->setIcon(0,QIcon(":/report/images/folder")); + QTreeWidgetItem *systemVariables =new QTreeWidgetItem(QStringList(tr("System variables")),DataBrowserTree::Category); + systemVariables->setIcon(0,QIcon(":/report/images/folder")); + ui->variablesTree->addTopLevelItem(userVariables); + ui->variablesTree->addTopLevelItem(systemVariables); + + foreach(QString variableName,m_report->dataManager()->variableNames()){ + QStringList values; + values<dataManager()->variableIsSystem(variableName))? + "": + " ["+m_report->dataManager()->variable(variableName).toString()+"]" + ) + <setIcon(0,QIcon(":/databrowser/images/value")); + if (m_report->dataManager()->variableIsSystem(variableName)){ + systemVariables->addChild(item); + } else { + userVariables->addChild(item); + } + } + + ui->variablesTree->expandItem(userVariables); + ui->variablesTree->expandItem(systemVariables); +} + +void DataBrowser::closeAllDataWindows() +{ + m_closingWindows = true; + QMap::iterator it = m_dataWindows.begin(); + for(;it!=m_dataWindows.end();){ + (*it)->close(); + delete (*it); + it = m_dataWindows.erase(it); + } + m_closingWindows = false; +} + +void DataBrowser::setSettings(QSettings *value, bool owned) +{ + if (m_settings && m_ownedSettings) delete m_settings; + m_settings=value; + m_ownedSettings = owned; +} + +QSettings *DataBrowser::settings() +{ + if (m_settings){ + return m_settings; + } else { + m_settings = new QSettings("LimeReport",QApplication::applicationName()); + m_ownedSettings = true; + return m_settings; + } +} + +void DataBrowser::slotDatasourcesChanged() +{ + updateDataTree(); +} + +void DataBrowser::fillFields(QTreeWidgetItem *parentItem, LimeReport::IDataSource *dataSource) +{ + if (!dataSource) return; + for (int i=0;icolumnCount();i++){ + QTreeWidgetItem *item = new QTreeWidgetItem(QStringList(dataSource->columnNameByIndex(i)),DataBrowserTree::Row); + item->setIcon(0,QIcon(":/databrowser/images/field")); + parentItem->addChild(item); + } + parentItem->sortChildren(0,Qt::AscendingOrder); +} + +QTreeWidgetItem * DataBrowser::findByNameAndType(QString name, int itemType) +{ + if (name.isEmpty()) return 0; + QListitems = ui->dataTree->findItems(name,Qt::MatchContains | Qt::MatchRecursive); + if (!items.isEmpty()){ + for (int i=0;itype()==itemType)/* && (items.at(0)->text(0)==name)*/){ return items.at(i);} + } + } + return 0; +} + +void DataBrowser::slotViewDatasource() +{ + QString datasourceName=getDatasourceName(); + if (!datasourceName.isEmpty()){ + showDataWindow(datasourceName); + } +} + +QString DataBrowser::getDatasourceName() +{ + if (ui->dataTree->currentItem()){ + if (ui->dataTree->currentItem()->type() == DataBrowserTree::Table) return ui->dataTree->currentItem()->text(0); + if (ui->dataTree->currentItem()->type() == DataBrowserTree::Row) return ui->dataTree->currentItem()->parent()->text(0); + }; + return QString(); +} + +QTreeWidgetItem* findConnectionItem(QTreeWidgetItem* item){ + if (item->type() == DataBrowserTree::Connection){ + return item; + } else { + if (item->parent()) + return findConnectionItem(item->parent()); + else + return 0; + } +} + +QString DataBrowser::getConnectionName() +{ + if (ui->dataTree->currentItem()){ + QTreeWidgetItem * ci = findConnectionItem(ui->dataTree->currentItem()); + if (ci) return ci->text(0); + else return QString(); + }; + return QString(); +} + +QString DataBrowser::getVariable() +{ + if(ui->variablesTree->currentItem()&&ui->variablesTree->currentItem()->type() == DataBrowserTree::Variable){ + return ui->variablesTree->currentItem()->text(1); + } + return QString(); +} + +void DataBrowser::slotEditDatasource() +{ + if (!getDatasourceName().isEmpty()){ + closeDataWindow(getDatasourceName()); + SQLEditDialog *sqlEdit = new SQLEditDialog(this,m_report->dataManager(),SQLEditDialog::EditMode); + sqlEdit->setAttribute(Qt::WA_DeleteOnClose); +#if defined(WIN32) || defined(WIN64) + sqlEdit->setWindowModality(Qt::ApplicationModal); +#else + sqlEdit->setWindowModality(Qt::WindowModal); +#endif + sqlEdit->setSettings(settings()); + sqlEdit->setDataSources(m_report->dataManager(),getDatasourceName()); + connect(sqlEdit,SIGNAL(signalSqlEditingFinished(SQLEditResult)),this,SLOT(slotSQLEditingFinished(SQLEditResult))); + sqlEdit->exec(); + } +} + +void DataBrowser::slotDeleteDatasource() +{ + QString datasourceName=getDatasourceName(); + QTreeWidgetItem *item = findByNameAndType(datasourceName, DataBrowserTree::Table); + if (item){ + if ( + QMessageBox::critical( + this, + tr("Attention"), + tr("Do you really want delete \"%1\" datasource ?").arg(datasourceName), + QMessageBox::Ok|QMessageBox::No, + QMessageBox::No + )==QMessageBox::Ok + ){ + removeDatasource(datasourceName); + } + } +} + +void DataBrowser::setReportEditor(LimeReport::ReportDesignWidget *report) +{ + m_report=report; + connect(m_report,SIGNAL(cleared()),this,SLOT(slotClear())); + connect(m_report->dataManager(), SIGNAL(datasourcesChanged()), this, SLOT(slotDatasourcesChanged())); + updateDataTree(); + updateVariablesTree(); +} + +void DataBrowser::slotClear() +{ + ui->dataTree->clear(); + foreach(QDockWidget* window,m_dataWindows.values()) window->close(); + updateDataTree(); +} + +void DataBrowser::initConnections() +{ + ui->dataTree->clear(); + QListitems; + foreach(QString connectionName,m_report->dataManager()->connectionNames()){ + QTreeWidgetItem *item=new QTreeWidgetItem(ui->dataTree,QStringList(connectionName), DataBrowserTree::Connection); + if (m_report->dataManager()->isConnectionConnected(connectionName)) + item->setIcon(0,QIcon(":/databrowser/images/database_connected")); + else + item->setIcon(0,QIcon(":/databrowser/images/database_disconnected")); + items.append(item); + } + ui->dataTree->insertTopLevelItems(0,items); +} + +QDockWidget *DataBrowser::createDataWindow(QString datasourceName) +{ + QDockWidget *window = new QDockWidget("Table: "+datasourceName); + QTableView *tableView = new QTableView(window); + //TODO: exception or message ? + + try { + IDataSource* datasource = m_report->dataManager()->dataSource(datasourceName); + if (datasource){ + tableView->setModel(datasource->model()); + } + } catch (ReportError& exception) { + qDebug()<setWidget(tableView); + window->setAttribute(Qt::WA_DeleteOnClose); + connect(window,SIGNAL(destroyed()),this,SLOT(slotDataWindowClosed())); + + if (!m_dataWindows.isEmpty()) + m_mainWindow->tabifyDockWidget(m_dataWindows.values().at(0),window); + else + m_mainWindow->addDockWidget(Qt::BottomDockWidgetArea,window); + + m_dataWindows.insert(datasourceName,window); + + return window; +} + +QDockWidget *DataBrowser::dataWindow(QString datasourceName) +{ + if (m_dataWindows.contains(datasourceName)){ + return m_dataWindows.value(datasourceName); + } else return createDataWindow(datasourceName); +} + +void DataBrowser::setMainWindow(QMainWindow *mainWindow) +{ + m_mainWindow=mainWindow; +} + +void DataBrowser::slotDataWindowClosed() +{ + if (isClosingWindows()) return; + for (int i=0;idataManager()->connectionByName(getConnectionName()), + this + ); + connectionEdit->setAttribute(Qt::WA_DeleteOnClose,true); +#if defined(WIN32) || defined(WIN64) + connectionEdit->setWindowModality(Qt::ApplicationModal); +#else + connectionEdit->setWindowModality(Qt::WindowModal); +#endif + //connect(connectionEdit,SIGNAL(finished(int)),this,SLOT(slotConnectionEditFinished(int))); + connectionEdit->exec(); + } +} + +void DataBrowser::slotChangeConnectionState() +{ + QString connectionName = getConnectionName(); + if (!connectionName.isEmpty()){ + if (!m_report->dataManager()->isConnectionConnected(connectionName)){ + setCursor(Qt::WaitCursor); + //try { + if (!m_report->dataManager()->connectConnection(connectionName)){ + //} catch(std::runtime_error &exception) { + QMessageBox::critical(this,tr("Attention"),m_report->dataManager()->lastError()); + //} + } + updateDataTree(); + setCursor(Qt::ArrowCursor); + } else { + m_report->dataManager()->disconnectConnection(connectionName); + updateDataTree(); + } + } +} + +void DataBrowser::slotVariableEditorAccept(const QString &variable) +{ + updateVariablesTree(); + QList items = ui->variablesTree->findItems(variable, Qt::MatchContains | Qt::MatchRecursive); + if (!items.isEmpty()){ + ui->variablesTree->setCurrentItem(items.at(0)); + } +} + +void DataBrowser::showDataWindow(QString datasourceName) +{ + QDockWidget *window = dataWindow(datasourceName); + if (window){ + window->show(); + window->raise(); + } +} + +void DataBrowser::closeDataWindow(QString datasourceName) +{ + if (m_dataWindows.contains(datasourceName)) + m_dataWindows.value(datasourceName)->close(); +} + +void DataBrowser::removeDatasource(QString datasourceName) +{ + closeDataWindow(datasourceName); + m_report->dataManager()->removeDatasource(datasourceName); +} + +void DataBrowser::addQuery(SQLEditResult result) +{ + try { + m_report->dataManager()->addQuery(result.datasourceName, result.sql, result.connectionName); + } catch(ReportError &exception){ + qDebug()<dataManager()->removeDatasource(result.oldDatasourceName); + m_report->dataManager()->addQuery(result.datasourceName, result.sql, result.connectionName); + }catch(ReportError &exception){ + qDebug()<dataManager()->addSubQuery(result.datasourceName, result.sql, result.connectionName, result.masterDatasource); + } catch(ReportError &exception){ + qDebug()<dataManager()->removeDatasource(result.oldDatasourceName); + m_report->dataManager()->addSubQuery(result.datasourceName, result.sql, result.connectionName, result.masterDatasource); + }catch(ReportError &exception){ + qDebug()<dataManager()->addProxy(result.datasourceName,result.masterDatasource,result.childDataSource,result.fieldMap); + } catch(ReportError &exception){ + qDebug()<dataManager()->removeDatasource(result.oldDatasourceName); + m_report->dataManager()->addProxy(result.datasourceName,result.masterDatasource,result.childDataSource,result.fieldMap); + } catch(ReportError &exception){ + qDebug()<dataManager()->addConnectionDesc(connection); + updateDataTree(); +} + +void DataBrowser::changeConnectionDesc(ConnectionDesc *connection) +{ + Q_UNUSED(connection) + updateDataTree(); +} + +void DataBrowser::on_dataTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) +{ + Q_UNUSED(previous) + if (current&&(current->type() == DataBrowserTree::Connection)) { + ui->pbConnect->setEnabled(true); + if (m_report->dataManager()->isConnectionConnected(current->text(0))){ + ui->pbConnect->setIcon(QIcon(":/databrowser/images/plug-connect.png")); + } else { + ui->pbConnect->setIcon(QIcon(":/databrowser/images/plug-disconnect.png")); + } + ui->editDataSource->setEnabled(false); + ui->deleteDataSource->setEnabled(false); + ui->viewDataSource->setEnabled(false); + ui->changeConnection->setEnabled(true); + ui->deleteConection->setEnabled(true); + ui->errorMessage->setDisabled(true); + } else { + ui->changeConnection->setEnabled(false); + ui->deleteConection->setEnabled(false); + ui->pbConnect->setEnabled(false); + IDataSourceHolder* holder = m_report->dataManager()->dataSourceHolder(getDatasourceName()); + if (holder){ + ui->viewDataSource->setEnabled(!holder->isInvalid()); + ui->editDataSource->setEnabled(holder->isEditable()); + ui->deleteDataSource->setEnabled(holder->isRemovable()); + if (!holder->lastError().isEmpty()){ + ui->errorMessage->setEnabled(true); + } else {ui->errorMessage->setEnabled(false);} + } + } +} + +void LimeReport::DataBrowser::on_addVariable_clicked() +{ + LRVariableDialog dialog(this); +#if defined(WIN32) || defined(WIN64) + dialog.setWindowModality(Qt::ApplicationModal); +#else + dialog.setWindowModality(Qt::WindowModal); +#endif + dialog.setVariableContainer(m_report->dataManager()); + connect(&dialog,SIGNAL(signalVariableAccepted(QString)),this,SLOT(slotVariableEditorAccept(QString))); + dialog.exec(); + +} + +void DataBrowser::on_editVariable_clicked() +{ + if (!getVariable().isEmpty()) + { + LRVariableDialog dialog(this); +#if defined(WIN32) || defined(WIN64) + dialog.setWindowModality(Qt::ApplicationModal); +#else + dialog.setWindowModality(Qt::WindowModal); +#endif + dialog.setVariableContainer(m_report->dataManager()); + QString varName = getVariable(); + dialog.setVariableName(varName); + connect(&dialog,SIGNAL(signalVariableAccepted(QString)),this,SLOT(slotVariableEditorAccept(QString))); + dialog.exec(); + } +} + +void DataBrowser::on_deleteVariable_clicked() +{ + QString varName = getVariable(); + if (!varName.isEmpty()){ + if (QMessageBox::critical(this,tr("Attention"),QString(tr("Do you really want delete variable \"%1\" ?")).arg(varName), + QMessageBox::Ok|QMessageBox::Cancel, QMessageBox::Cancel + )==QMessageBox::Ok){ + m_report->dataManager()->deleteVariable(varName); + updateVariablesTree(); + } + } +} + +void DataBrowser::on_variablesTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) +{ + Q_UNUSED(previous) + + if (current){ + if (m_report->dataManager()->containsVariable(current->text(1))&& + !m_report->dataManager()->variableIsSystem(current->text(1)) + ){ + ui->editVariable->setEnabled(true); + ui->deleteVariable->setEnabled(true); + } else { + ui->editVariable->setEnabled(false); + ui->deleteVariable->setEnabled(false); + } + } +} + +void DataBrowser::on_errorMessage_clicked() +{ + if(!getDatasourceName().isEmpty()&&m_report->dataManager()->dataSourceHolder(getDatasourceName())){ + QMessageBox::critical(this,tr("Error"),m_report->dataManager()->dataSourceHolder(getDatasourceName())->lastError()); + } +} + +} // namespace LimeReport + + + + diff --git a/src/databrowser/lrdatabrowser.h b/src/databrowser/lrdatabrowser.h new file mode 100644 index 0000000..06b10d3 --- /dev/null +++ b/src/databrowser/lrdatabrowser.h @@ -0,0 +1,115 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRDATABROWSER_H +#define LRDATABROWSER_H + +#include +#include +#include +#include + +#include "lrreportdesignwidget.h" +#include "lrsqleditdialog.h" + +namespace Ui { + class DataBrowser; +} +namespace LimeReport{ + +class DataBrowser : public QWidget, public IConnectionController +{ + Q_OBJECT +public: + + explicit DataBrowser(QWidget *parent = 0); + ~DataBrowser(); + QSize sizeHint() const; + void setReportEditor(LimeReport::ReportDesignWidget* report); + void setMainWindow(QMainWindow* mainWindow); + void initConnections(); + void updateDataTree(); + void updateVariablesTree(); + void closeAllDataWindows(); + void setSettings(QSettings* value, bool owned = false); + QSettings* settings(); +private slots: + void slotDatasourcesChanged(); + void slotAddConnection(); + void slotDeleteConnection(); + void slotAddDataSource(); + void slotViewDatasource(); + void slotEditDatasource(); + void slotDeleteDatasource(); + void slotSQLEditingFinished(SQLEditResult result); + void slotClear(); + void slotDataWindowClosed(); + void slotChangeConnection(); + void slotChangeConnectionState(); + void slotVariableEditorAccept(const QString &variable); + void on_dataTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); + void on_editVariable_clicked(); + void on_deleteVariable_clicked(); + void on_addVariable_clicked(); + void on_variablesTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); + void on_errorMessage_clicked(); +private: + QString getDatasourceName(); + QString getConnectionName(); + QString getVariable(); + bool isClosingWindows() const {return m_closingWindows;} + QTreeWidgetItem * findByNameAndType(QString name, int itemType); + void fillFields(QTreeWidgetItem *parentItem, LimeReport::IDataSource *dataSource); + QDockWidget* createDataWindow(QString datasourceName); + void closeDataWindow(QString datasourceName); + QDockWidget* dataWindow(QString datasourceName); + void showDataWindow(QString datasourceName); + void removeDatasource(QString datasourceName); + void addQuery(SQLEditResult result); + void changeQuery(SQLEditResult result); + void addSubQuery(SQLEditResult result); + void changeSubQuery(SQLEditResult result); + void addProxy(SQLEditResult result); + void changeProxy(SQLEditResult result); + + void addConnectionDesc(ConnectionDesc *connection); + void changeConnectionDesc(ConnectionDesc *connection); + +private: + Ui::DataBrowser* ui; + ReportDesignWidget* m_report; + QMap m_dataWindows; + QMainWindow* m_mainWindow; + bool m_closingWindows; + QSettings* m_settings; + bool m_ownedSettings; +}; + +} +#endif // LRDATABROWSER_H diff --git a/src/databrowser/lrdatabrowser.qrc b/src/databrowser/lrdatabrowser.qrc new file mode 100644 index 0000000..7a46b64 --- /dev/null +++ b/src/databrowser/lrdatabrowser.qrc @@ -0,0 +1,47 @@ + + + images/data_add.png + images/data_delete.png + images/table.png + images/table_delete.png + images/data.png + images/row.png + images/edit_table.png + images/table_view.png + images/value_add.png + images/value_delete.png + images/value_edit.png + images/value.png + images/data_edit.png + images/add.png + images/remove.png + images/plug-connect.png + images/plug-disconnect.png + images/database_connect.png + images/database_disconnect.png + images/database_connected.png + images/database_connected2.png + images/table_error.png + images/table_good.png + images/error_message.png + images/error_message_2.png + images/data1.png + images/database_connected3.png + images/field.png + images/table_error1.png + images/table_good1.png + images/data_add1.png + images/data_delete1.png + images/data_edit1.png + images/table_add.png + images/table_delete1.png + images/table_edit.png + images/table_view1.png + images/value_add1.png + images/value_delete1.png + images/value_edit1.png + images/value_add2.png + images/value_edit2.png + images/value1.png + + diff --git a/src/databrowser/lrdatabrowser.ui b/src/databrowser/lrdatabrowser.ui new file mode 100644 index 0000000..f5c4a05 --- /dev/null +++ b/src/databrowser/lrdatabrowser.ui @@ -0,0 +1,484 @@ + + + DataBrowser + + + + 0 + 0 + 400 + 300 + + + + Datasources + + + + 1 + + + 1 + + + 1 + + + 1 + + + 2 + + + + + QTabWidget::South + + + 0 + + + + Datasources + + + + 2 + + + 2 + + + 2 + + + 2 + + + + + 2 + + + + + Add database connection + + + ... + + + + :/databrowser/images/database_add:/databrowser/images/database_add + + + + 16 + 16 + + + + true + + + + + + + false + + + ... + + + + :/databrowser/images/database_edit:/databrowser/images/database_edit + + + + 16 + 16 + + + + true + + + + + + + false + + + ... + + + + :/databrowser/images/database_delete:/databrowser/images/database_delete + + + + 16 + 16 + + + + true + + + + + + + false + + + ... + + + + :/databrowser/images/plug-connect.png:/databrowser/images/plug-connect.png + + + + 16 + 16 + + + + true + + + + + + + QFrame::VLine + + + QFrame::Sunken + + + + + + + + + + ... + + + + :/databrowser/images/table_add:/databrowser/images/table_add + + + + 16 + 16 + + + + true + + + + + + + false + + + ... + + + + :/databrowser/images/table_view:/databrowser/images/table_view + + + + 16 + 16 + + + + true + + + + + + + false + + + ... + + + + :/databrowser/images/table_edit:/databrowser/images/table_edit + + + + 16 + 16 + + + + true + + + + + + + false + + + ... + + + + :/databrowser/images/table_delete:/databrowser/images/table_delete + + + + 16 + 16 + + + + true + + + + + + + false + + + ... + + + + :/databrowser/images/error_message_2.png:/databrowser/images/error_message_2.png + + + + 16 + 16 + + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + true + + + true + + + QAbstractItemView::DragOnly + + + false + + + + 1 + + + + + + + + + Variables + + + + 2 + + + 2 + + + 2 + + + 2 + + + + + 2 + + + + + ... + + + + :/databrowser/images/value_add:/databrowser/images/value_add + + + + 16 + 16 + + + + QToolButton::DelayedPopup + + + true + + + + + + + false + + + ... + + + + :/databrowser/images/value_edit:/databrowser/images/value_edit + + + + 16 + 16 + + + + true + + + + + + + false + + + ... + + + + :/databrowser/images/value_delete:/databrowser/images/value_delete + + + + 16 + 16 + + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + true + + + QAbstractItemView::DragOnly + + + true + + + 1 + + + false + + + + 1 + + + + + + + + + + + + + DataBrowserTree + QTreeWidget +
lrdatabrowsertree.h
+
+
+ + dataTree + addConnection + changeConnection + deleteConection + pbConnect + addDataSource + viewDataSource + editDataSource + deleteDataSource + variablesTree + addVariable + editVariable + deleteVariable + tabWidget + + + + + + + slotAddDataSource() + slotDeleteDataSource() + +
diff --git a/src/databrowser/lrdatabrowsertree.cpp b/src/databrowser/lrdatabrowsertree.cpp new file mode 100644 index 0000000..b1fb944 --- /dev/null +++ b/src/databrowser/lrdatabrowsertree.cpp @@ -0,0 +1,47 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrdatabrowsertree.h" +#include +#include + +DataBrowserTree::DataBrowserTree(QWidget *parent) : + QTreeWidget(parent){} + +QMimeData *DataBrowserTree::mimeData(const QList items) const +{ + QMimeData* result = QTreeWidget::mimeData(items); + if (items.at(0)->type()==Row){ + result->setText("$D{"+items.at(0)->parent()->text(0)+"."+items.at(0)->data(0,Qt::DisplayRole).toString()+"}"); + } + if (items.at(0)->type()==Variable){ + result->setText("$V{"+items.at(0)->text(0)+"}"); + } + return result; +} diff --git a/src/databrowser/lrdatabrowsertree.h b/src/databrowser/lrdatabrowsertree.h new file mode 100644 index 0000000..1a44eb5 --- /dev/null +++ b/src/databrowser/lrdatabrowsertree.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRDATABROWSERTREE_H +#define LRDATABROWSERTREE_H + +#include + +class DataBrowserTree : public QTreeWidget +{ + Q_OBJECT +public: + enum NodeType{Connection,Table,Row,Category,Variable}; + explicit DataBrowserTree(QWidget *parent = 0); +protected: + QMimeData* mimeData(const QList items) const; + +public slots: + +}; + +#endif // LRDATABROWSERTREE_H diff --git a/src/databrowser/lrsqleditdialog.cpp b/src/databrowser/lrsqleditdialog.cpp new file mode 100644 index 0000000..ca20a32 --- /dev/null +++ b/src/databrowser/lrsqleditdialog.cpp @@ -0,0 +1,343 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrsqleditdialog.h" +#include "ui_lrsqleditdialog.h" +#include "lrreportengine_p.h" + +#include +#include +#include + +SQLEditDialog::SQLEditDialog(QWidget *parent, LimeReport::DataSourceManager *dataSources, SQLDialogMode dialogMode) : + QDialog(parent), + ui(new Ui::SQLEditDialog),m_datasources(dataSources),m_dialogMode(dialogMode), m_oldDatasourceName(""), + m_settings(0), m_ownedSettings(false) +{ + ui->setupUi(this); + m_masterDatasources = new QCompleter(this); + ui->leMaster->setCompleter(m_masterDatasources); + ui->leChild->setCompleter(m_masterDatasources); + ui->gbFieldsMap->setVisible(false); + ui->gbDataPreview->setVisible(false); + ui->pbHidePreview->setVisible(false); + ui->rbSubQuery->setChecked(true); + ui->rbProxy->setVisible(false); + ui->rbSubQuery->setVisible(false); + ui->leMaster->setVisible(false); + ui->lbMaster->setVisible(false); + ui->fieldsMap->setHorizontalHeaderItem(0,new QTableWidgetItem("master")); + ui->fieldsMap->setHorizontalHeaderItem(1,new QTableWidgetItem("detail")); + +#ifdef HAVE_QT5 + ui->fieldsMap->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); +#else + ui->fieldsMap->horizontalHeader()->setResizeMode(QHeaderView::Stretch); +#endif + ui->pnlChildDatasource->setVisible(false); + connect(ui->pbPreview, SIGNAL(pressed()), this, SLOT(slotPreviewData())); + connect(ui->pbHidePreview, SIGNAL(pressed()), this, SLOT(slotHidePreview())); +} + +SQLEditDialog::~SQLEditDialog() +{ + delete ui; + if (m_settings && m_ownedSettings) + delete m_settings; +} + +QSettings *SQLEditDialog::settings(){ + if (m_settings){ + return m_settings; + } else { + m_settings = new QSettings("LimeReport",QApplication::applicationName()); + m_ownedSettings = true; + return m_settings; + } +} + +void SQLEditDialog::setSettings(QSettings *value, bool owned){ + if (m_settings && m_ownedSettings) delete m_settings; + m_settings=value; + m_ownedSettings = owned; +} + +void SQLEditDialog::accept() +{ + SQLEditResult result; + + if (!ui->cbSubdetail->isChecked()){ + result.resultMode=SQLEditResult::Query; + } else { + if (ui->rbSubQuery->isChecked()) result.resultMode=SQLEditResult::SubQuery; + else result.resultMode=SQLEditResult::SubProxy; + } + + result.connectionName=ui->cbbConnection->currentText(); + result.datasourceName=ui->leDatasourceName->text(); + result.sql=ui->textEditSQL->toPlainText(); + result.dialogMode=m_dialogMode; + result.oldDatasourceName=m_oldDatasourceName; + result.subdetail = ui->cbSubdetail->isChecked(); + result.masterDatasource=ui->leMaster->text(); + result.childDataSource=ui->leChild->text(); + + if (ui->fieldsMap->rowCount()>0){ + for(int i=0;ifieldsMap->rowCount();++i){ + LimeReport::FieldsCorrelation fieldsCorrelation; + fieldsCorrelation.master=ui->fieldsMap->item(i,0)->data(Qt::DisplayRole).toString(); + fieldsCorrelation.detail=ui->fieldsMap->item(i,1)->data(Qt::DisplayRole).toString(); + result.fieldMap.append(fieldsCorrelation); + } + } + + try { + check(); + emit signalSqlEditingFinished(result); + QDialog::accept(); + }catch(LimeReport::ReportError &exception){ + QMessageBox::critical(this,tr("Error"),exception.what()); + } +} + +void SQLEditDialog::showEvent(QShowEvent *) +{ + ui->lblInfo->setVisible(false); + initConnections(); + readSettings(); +} + +void SQLEditDialog::closeEvent(QCloseEvent *) +{ + writeSetting(); +} + +void SQLEditDialog::hideEvent(QHideEvent *) +{ + writeSetting(); +} + +void SQLEditDialog::check() +{ + if (ui->leDatasourceName->text().isEmpty()) throw LimeReport::ReportError(tr("Datasource Name is empty !")); + if (ui->textEditSQL->toPlainText().isEmpty() && (!ui->rbProxy) ) throw LimeReport::ReportError(tr("SQL is empty !")); + if (m_dialogMode==AddMode){ + if (m_datasources->containsDatasource(ui->leDatasourceName->text())){ + throw LimeReport::ReportError(QString(tr("Datasource with name: \"%1\" already exists !")).arg(ui->leDatasourceName->text())); + } + } +} + +void SQLEditDialog::initConnections() +{ + foreach(QString connectionName, QSqlDatabase::connectionNames()){ + ui->cbbConnection->addItem(QIcon(":/databrowser/images/plug-connect.png"),connectionName); + } + foreach(QString connectionName, m_datasources->connectionNames()){ + if (ui->cbbConnection->findText(connectionName,Qt::MatchExactly )==-1) + ui->cbbConnection->addItem(QIcon(":/databrowser/images/plug-disconnect.png"),connectionName); + } + ui->cbbConnection->setCurrentIndex(ui->cbbConnection->findText(m_defaultConnection)); + if (!m_oldDatasourceName.isEmpty()){ + ui->cbbConnection->setCurrentIndex(ui->cbbConnection->findText(m_datasources->connectionName(m_oldDatasourceName))); + } +} + +void SQLEditDialog::setDataSources(LimeReport::DataSourceManager *dataSources, QString datasourceName) +{ + m_datasources=dataSources; + if (!datasourceName.isEmpty()){ + ui->cbSubdetail->setEnabled(false); + initQueryMode(); + m_oldDatasourceName=datasourceName; + ui->leDatasourceName->setText(datasourceName); + ui->textEditSQL->setText(dataSources->queryText(datasourceName)); + if (dataSources->isSubQuery(datasourceName)){ + initSubQueryMode(); + ui->leMaster->setText(dataSources->subQueryByName(datasourceName)->master()); + } + if (dataSources->isProxy(datasourceName)){ + initProxyMode(); + LimeReport::ProxyDesc* proxyDesc = dataSources->proxyByName(datasourceName); + ui->leChild->setText(proxyDesc->child()); + ui->leMaster->setText(proxyDesc->master()); + int curIndex=0; + foreach(LimeReport::FieldMapDesc* fields, *proxyDesc->fieldsMap()){ + ui->fieldsMap->setRowCount(curIndex+1); + ui->fieldsMap->setItem(curIndex,0,new QTableWidgetItem(fields->master())); + ui->fieldsMap->setItem(curIndex,1,new QTableWidgetItem(fields->detail())); + curIndex++; + } + } + } +} + +void SQLEditDialog::setDefaultConnection(QString defaultConnection) +{ + m_defaultConnection=defaultConnection; +} + +void SQLEditDialog::slotDataSourceNameEditing() +{ + if (m_dialogMode==AddMode){ + QPalette palette=ui->leDatasourceName->palette(); + if (m_datasources->containsDatasource(ui->leDatasourceName->text())){ + palette.setColor(QPalette::Text,Qt::red); + ui->leDatasourceName->setPalette(palette); + ui->lblInfo->setText(QString(tr("Datasource with name %1 already exist")).arg(ui->leDatasourceName->text())); + ui->lblInfo->setVisible(true); + } else { + palette.setColor(QPalette::Text,QApplication::palette().text().color()); + ui->leDatasourceName->setPalette(palette); + ui->lblInfo->setVisible(false); + } + } +} + +void SQLEditDialog::on_cbSubdetail_clicked(bool checked) +{ + if (checked){ + m_masterDatasources->setModel(new QStringListModel(m_datasources->dataSourceNames(),m_datasources)); + } + ui->leMaster->setEnabled(checked); + ui->rbProxy->setEnabled(checked); + ui->rbSubQuery->setEnabled(checked); + if ((checked)&&(ui->rbProxy->isChecked())) initProxyMode(); + if ((checked)&&(ui->rbSubQuery->isChecked())) initSubQueryMode(); + if (!checked) initQueryMode(); +} + +void SQLEditDialog::on_rbProxy_clicked(bool checked) +{ + if (checked) initProxyMode(); +} + +void SQLEditDialog::on_rbSubQuery_clicked(bool checked) +{ + if (checked) initSubQueryMode(); +} + +void SQLEditDialog::on_pbAddField_clicked() +{ + ui->fieldsMap->setRowCount(ui->fieldsMap->rowCount()+1); +} + +void SQLEditDialog::initQueryMode() +{ + ui->gbSQL->setVisible(true); + ui->gbFieldsMap->setVisible(false); + ui->pnlChildDatasource->setVisible(false); + ui->rbSubQuery->setVisible(false); + ui->rbProxy->setVisible(false); + ui->cbSubdetail->setChecked(false); + ui->leMaster->setVisible(false); + ui->lbMaster->setVisible(false); +} + +void SQLEditDialog::initSubQueryMode() +{ + ui->gbSQL->setVisible(true); + ui->gbFieldsMap->setVisible(false); + ui->pnlChildDatasource->setVisible(false); + ui->rbSubQuery->setChecked(true); + ui->cbSubdetail->setChecked(true); + ui->rbSubQuery->setVisible(true); + ui->rbProxy->setVisible(true); + ui->leMaster->setVisible(true); + ui->leMaster->setEnabled(true); + ui->lbMaster->setVisible(true); + +} + +void SQLEditDialog::initProxyMode() +{ + ui->gbSQL->setVisible(false); + ui->gbFieldsMap->setVisible(true); + ui->pnlChildDatasource->setVisible(true); + ui->rbProxy->setChecked(true); + ui->cbSubdetail->setChecked(true); + ui->rbSubQuery->setVisible(true); + ui->rbProxy->setVisible(true); + ui->leMaster->setVisible(true); + ui->leMaster->setEnabled(true); + ui->lbMaster->setVisible(true); + ui->cbSubdetail->setEnabled(false); +} + +void SQLEditDialog::slotPreviewData() +{ + if (ui->cbbConnection->currentText().isEmpty()){ + QMessageBox::critical(this,tr("Attention"),tr("Connection is not specified")); + return; + } + m_previewModel = m_datasources->previewSQL(ui->cbbConnection->currentText(),ui->textEditSQL->toPlainText()); + if (m_previewModel){ + ui->tvPreview->setModel(m_previewModel.data()); + ui->gbDataPreview->setVisible(true); + ui->pbPreview->setText(tr("Refresh")); + ui->pbHidePreview->setVisible(true); + } else { + if (ui->gbDataPreview->isVisible()) + hidePreview(); + QMessageBox::critical(this,tr("Attention"),m_datasources->lastError()); + } +} + +void SQLEditDialog::slotHidePreview() +{ + hidePreview(); +} + +void SQLEditDialog::writeSetting() +{ + if (settings()!=0){ + settings()->beginGroup("SQLEditor"); + settings()->setValue("Geometry",saveGeometry()); + settings()->endGroup(); + } +} + +void SQLEditDialog::readSettings() +{ + if (settings()==0) return; + settings()->beginGroup("SQLEditor"); + QVariant v = settings()->value("Geometry"); + if (v.isValid()){ + restoreGeometry(v.toByteArray()); + } + settings()->endGroup(); +} + +void SQLEditDialog::hidePreview() +{ + ui->gbDataPreview->setVisible(false); + ui->pbPreview->setText(tr("Preview")); + ui->pbHidePreview->setVisible(false); +} + diff --git a/src/databrowser/lrsqleditdialog.h b/src/databrowser/lrsqleditdialog.h new file mode 100644 index 0000000..8122824 --- /dev/null +++ b/src/databrowser/lrsqleditdialog.h @@ -0,0 +1,109 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRSQLEDITDIALOG_H +#define LRSQLEDITDIALOG_H + +#include +#include +#include +#include +#include "lrreportengine_p.h" +#include "lrdatasourcemanager.h" +#include "lrdatadesignintf.h" + +namespace Ui { + class SQLEditDialog; +} + +struct SQLEditResult; + +class SQLEditDialog : public QDialog +{ + Q_OBJECT + +public: + enum SQLDialogMode {AddMode,EditMode}; + explicit SQLEditDialog(QWidget *parent, LimeReport::DataSourceManager* dataSources,SQLDialogMode dialogMode); + void setDataSources(LimeReport::DataSourceManager *dataSources,QString datasourceName=""); + void setDefaultConnection(QString defaultConnection); + ~SQLEditDialog(); + QSettings* settings(); + void setSettings(QSettings* value, bool owned = false); +signals: + void signalSqlEditingFinished(SQLEditResult result); +protected: + void showEvent(QShowEvent *); + void closeEvent(QCloseEvent*); + void hideEvent(QHideEvent*); + void check(); + void initConnections(); +private slots: + void accept(); + void slotDataSourceNameEditing(); + void on_cbSubdetail_clicked(bool checked); + void on_rbProxy_clicked(bool checked); + void on_rbSubQuery_clicked(bool checked); + void on_pbAddField_clicked(); + void initQueryMode(); + void initSubQueryMode(); + void initProxyMode(); + void slotPreviewData(); + void slotHidePreview(); +private: + void writeSetting(); + void readSettings(); + void hidePreview(); +private: + Ui::SQLEditDialog *ui; + LimeReport::DataSourceManager* m_datasources; + SQLDialogMode m_dialogMode; + QString m_oldDatasourceName; + QCompleter* m_masterDatasources; + QString m_defaultConnection; + QSettings* m_settings; + bool m_ownedSettings; + QSharedPointer m_previewModel; +}; + +struct SQLEditResult{ + enum ResultMode{Query,SubQuery,SubProxy}; + QString connectionName; + QString datasourceName; + QString oldDatasourceName; + QString sql; + bool subdetail; + ResultMode resultMode; + QString masterDatasource; + QString childDataSource; + SQLEditDialog::SQLDialogMode dialogMode; + QList fieldMap; +}; + +#endif // LRSQLEDITDIALOG_H diff --git a/src/databrowser/lrsqleditdialog.ui b/src/databrowser/lrsqleditdialog.ui new file mode 100644 index 0000000..9e9116c --- /dev/null +++ b/src/databrowser/lrsqleditdialog.ui @@ -0,0 +1,859 @@ + + + SQLEditDialog + + + + 0 + 0 + 411 + 617 + + + + Datasource + + + + :/databrowser/images/database_disconnected:/databrowser/images/database_disconnected + + + + + + + + + + + Connection + + + + + + + + 0 + 0 + + + + Qt::NoFocus + + + + + + + + + + + + + Datasource Name + + + + + + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 127 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 191 + + + + + + + 127 + 127 + 63 + + + + + + + 170 + 170 + 84 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 127 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 191 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 127 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 191 + + + + + + + 127 + 127 + 63 + + + + + + + 170 + 170 + 84 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 127 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 191 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + + 127 + 127 + 63 + + + + + + + 255 + 255 + 127 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 191 + + + + + + + 127 + 127 + 63 + + + + + + + 170 + 170 + 84 + + + + + + + 127 + 127 + 63 + + + + + + + 255 + 255 + 255 + + + + + + + 127 + 127 + 63 + + + + + + + 255 + 255 + 127 + + + + + + + 255 + 255 + 127 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 127 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + true + + + + + + -1 + + + + + + + + + + + Subdetail + + + + + + + + + Master datasource + + + + + + + false + + + + + + + + + false + + + Subquery mode + + + + + + + false + + + Filter mode + + + + + + + + + SQL + + + + 4 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Preview + + + + + + + Hide Preview + + + + + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + Child datasource + + + + + + + + + + + + + + + Fields map + + + + 4 + + + 4 + + + 4 + + + 4 + + + + + 2 + + + + + + + + + + + ... + + + + :/databrowser/images/add.png:/databrowser/images/add.png + + + true + + + + + + + ... + + + + :/databrowser/images/remove.png:/databrowser/images/remove.png + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + Data preview + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Cancel + + + false + + + + + + + Ok + + + false + + + + + + + + + leDatasourceName + cbSubdetail + leMaster + rbSubQuery + rbProxy + textEditSQL + leChild + fieldsMap + pbAddField + pbDelField + pushButton_2 + pushButton + + + + + + + leDatasourceName + textChanged(QString) + SQLEditDialog + slotDataSourceNameEditing() + + + 259 + 54 + + + 289 + 32 + + + + + pushButton + clicked() + SQLEditDialog + accept() + + + 397 + 536 + + + 380 + 360 + + + + + pushButton_2 + clicked() + SQLEditDialog + reject() + + + 278 + 538 + + + 299 + 383 + + + + + + slotDataSourceNameEditing() + + diff --git a/src/databrowser/lrvariabledialog.cpp b/src/databrowser/lrvariabledialog.cpp new file mode 100644 index 0000000..a2d5dec --- /dev/null +++ b/src/databrowser/lrvariabledialog.cpp @@ -0,0 +1,99 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrvariabledialog.h" +#include "ui_lrvariabledialog.h" +#include "lrglobal.h" +#include +#include + +LRVariableDialog::LRVariableDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::LRVariableDialog), + m_variableName(""), + m_variablesContainer(0), + m_changeMode(false), + m_oldVariableName("") +{ + ui->setupUi(this); + ui->cbbType->setVisible(false); + ui->lblType->setVisible(false); +} + +LRVariableDialog::~LRVariableDialog() +{ + delete ui; +} + +void LRVariableDialog::setVariableContainer(LimeReport::IVariablesContainer *value) +{ + m_variablesContainer=value; +} + +void LRVariableDialog::setVariableName(const QString &value) +{ + m_variableName=value; + m_changeMode=true; + m_oldVariableName=value; +} + +void LRVariableDialog::showEvent(QShowEvent *) +{ + ui->leName->setText(m_variableName); + if (!m_variableName.isEmpty()&&m_variablesContainer&&m_variablesContainer->containsVariable(m_variableName)){ + ui->leValue->setText(m_variablesContainer->variable(m_variableName).toString()); + } +} + +void LRVariableDialog::accept() +{ + try{ + if (m_variablesContainer&&!ui->leName->text().isEmpty()){ + if (m_changeMode){ + if (m_oldVariableName==ui->leName->text()){ + m_variablesContainer->changeVariable(m_oldVariableName,value()); + } else { + m_variablesContainer->deleteVariable(m_oldVariableName); + m_variablesContainer->addVariable(ui->leName->text(),value()); + } + } else { + m_variablesContainer->addVariable(ui->leName->text(),value()); + } + emit signalVariableAccepted(ui->leName->text()); + QDialog::accept(); + } + } catch (LimeReport::ReportError &exception){ + QMessageBox::critical(this,tr("Attention"),exception.what()); + } +} + +QVariant LRVariableDialog::value() +{ + return ui->leValue->text(); +} diff --git a/src/databrowser/lrvariabledialog.h b/src/databrowser/lrvariabledialog.h new file mode 100644 index 0000000..49ba046 --- /dev/null +++ b/src/databrowser/lrvariabledialog.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRVARIABLEDIALOG_H +#define LRVARIABLEDIALOG_H + +#include +#include "lrvariablesholder.h" + +namespace Ui { +class LRVariableDialog; +} + +class LRVariableDialog : public QDialog +{ + Q_OBJECT + +public: + explicit LRVariableDialog(QWidget *parent = 0); + ~LRVariableDialog(); + void setVariableContainer(LimeReport::IVariablesContainer *value); + void setVariableName(const QString &value); +protected: + void showEvent(QShowEvent *); +private slots: + void accept(); +signals: + void signalVariableAccepted(const QString &variable); +private: + QVariant value(); +private: + Ui::LRVariableDialog *ui; + QString m_variableName; + LimeReport::IVariablesContainer* m_variablesContainer; + bool m_changeMode; + QString m_oldVariableName; +}; + +#endif // LRVARIABLEDIALOG_H diff --git a/src/databrowser/lrvariabledialog.ui b/src/databrowser/lrvariabledialog.ui new file mode 100644 index 0000000..df97830 --- /dev/null +++ b/src/databrowser/lrvariabledialog.ui @@ -0,0 +1,131 @@ + + + LRVariableDialog + + + + 0 + 0 + 218 + 126 + + + + Variable + + + + :/databrowser/images/value:/databrowser/images/value + + + + 2 + + + 4 + + + 4 + + + 4 + + + 4 + + + + + 7 + + + 5 + + + 4 + + + 8 + + + + + Name + + + + + + + + + + Value + + + + + + + + + + + + + Type + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + LRVariableDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + LRVariableDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/images/Control-Edit Box.png b/src/images/Control-Edit Box.png new file mode 100644 index 0000000..ea0fb75 Binary files /dev/null and b/src/images/Control-Edit Box.png differ diff --git a/src/images/Hourglass_80.png b/src/images/Hourglass_80.png new file mode 100644 index 0000000..ce174d3 Binary files /dev/null and b/src/images/Hourglass_80.png differ diff --git a/src/images/addBand.png b/src/images/addBand.png new file mode 100644 index 0000000..d927ac9 Binary files /dev/null and b/src/images/addBand.png differ diff --git a/src/images/addBand1.png b/src/images/addBand1.png new file mode 100644 index 0000000..6496959 Binary files /dev/null and b/src/images/addBand1.png differ diff --git a/src/images/allLines.png b/src/images/allLines.png new file mode 100644 index 0000000..33925af Binary files /dev/null and b/src/images/allLines.png differ diff --git a/src/images/allLines1.png b/src/images/allLines1.png new file mode 100644 index 0000000..f613d30 Binary files /dev/null and b/src/images/allLines1.png differ diff --git a/src/images/barcode.png b/src/images/barcode.png new file mode 100644 index 0000000..19669cd Binary files /dev/null and b/src/images/barcode.png differ diff --git a/src/images/barcode1.png b/src/images/barcode1.png new file mode 100644 index 0000000..3360dd8 Binary files /dev/null and b/src/images/barcode1.png differ diff --git a/src/images/barcode2.png b/src/images/barcode2.png new file mode 100644 index 0000000..328a2ac Binary files /dev/null and b/src/images/barcode2.png differ diff --git a/src/images/barcode3_16.png b/src/images/barcode3_16.png new file mode 100644 index 0000000..80d9397 Binary files /dev/null and b/src/images/barcode3_16.png differ diff --git a/src/images/barcode3_24.png b/src/images/barcode3_24.png new file mode 100644 index 0000000..10fd139 Binary files /dev/null and b/src/images/barcode3_24.png differ diff --git a/src/images/bottomLine.png b/src/images/bottomLine.png new file mode 100644 index 0000000..70cacbd Binary files /dev/null and b/src/images/bottomLine.png differ diff --git a/src/images/bottomLine1.png b/src/images/bottomLine1.png new file mode 100644 index 0000000..6566228 Binary files /dev/null and b/src/images/bottomLine1.png differ diff --git a/src/images/bringToFront.png b/src/images/bringToFront.png new file mode 100644 index 0000000..b411bbf Binary files /dev/null and b/src/images/bringToFront.png differ diff --git a/src/images/closebox.png b/src/images/closebox.png new file mode 100644 index 0000000..46d90bc Binary files /dev/null and b/src/images/closebox.png differ diff --git a/src/images/copy.png b/src/images/copy.png new file mode 100644 index 0000000..c4a26b9 Binary files /dev/null and b/src/images/copy.png differ diff --git a/src/images/copy16.png b/src/images/copy16.png new file mode 100644 index 0000000..9c71808 Binary files /dev/null and b/src/images/copy16.png differ diff --git a/src/images/copy2.png b/src/images/copy2.png new file mode 100644 index 0000000..da050ea Binary files /dev/null and b/src/images/copy2.png differ diff --git a/src/images/copy24.png b/src/images/copy24.png new file mode 100644 index 0000000..4c21085 Binary files /dev/null and b/src/images/copy24.png differ diff --git a/src/images/copy_2_16.png b/src/images/copy_2_16.png new file mode 100644 index 0000000..db1d9fb Binary files /dev/null and b/src/images/copy_2_16.png differ diff --git a/src/images/copy_2_24.png b/src/images/copy_2_24.png new file mode 100644 index 0000000..9f556a0 Binary files /dev/null and b/src/images/copy_2_24.png differ diff --git a/src/images/cpyright_logo.png b/src/images/cpyright_logo.png new file mode 100644 index 0000000..d51095f Binary files /dev/null and b/src/images/cpyright_logo.png differ diff --git a/src/images/cut.png b/src/images/cut.png new file mode 100644 index 0000000..730625b Binary files /dev/null and b/src/images/cut.png differ diff --git a/src/images/cut1.png b/src/images/cut1.png new file mode 100644 index 0000000..8339751 Binary files /dev/null and b/src/images/cut1.png differ diff --git a/src/images/cut16.png b/src/images/cut16.png new file mode 100644 index 0000000..edd1844 Binary files /dev/null and b/src/images/cut16.png differ diff --git a/src/images/cut24.png b/src/images/cut24.png new file mode 100644 index 0000000..c87f288 Binary files /dev/null and b/src/images/cut24.png differ diff --git a/src/images/cut_1_24.png b/src/images/cut_1_24.png new file mode 100644 index 0000000..62af544 Binary files /dev/null and b/src/images/cut_1_24.png differ diff --git a/src/images/cut_24.png b/src/images/cut_24.png new file mode 100644 index 0000000..19a62ec Binary files /dev/null and b/src/images/cut_24.png differ diff --git a/src/images/dasabases.png b/src/images/dasabases.png new file mode 100644 index 0000000..94a9cb1 Binary files /dev/null and b/src/images/dasabases.png differ diff --git a/src/images/database.png b/src/images/database.png new file mode 100644 index 0000000..af7dd7e Binary files /dev/null and b/src/images/database.png differ diff --git a/src/images/delete.png b/src/images/delete.png new file mode 100644 index 0000000..a7ebb08 Binary files /dev/null and b/src/images/delete.png differ diff --git a/src/images/delete1.png b/src/images/delete1.png new file mode 100644 index 0000000..7c557a0 Binary files /dev/null and b/src/images/delete1.png differ diff --git a/src/images/design.png b/src/images/design.png new file mode 100644 index 0000000..c3fd61d Binary files /dev/null and b/src/images/design.png differ diff --git a/src/images/dialog-close.png b/src/images/dialog-close.png new file mode 100644 index 0000000..8f2ae53 Binary files /dev/null and b/src/images/dialog-close.png differ diff --git a/src/images/dialog-close_red.png b/src/images/dialog-close_red.png new file mode 100644 index 0000000..5cfdad3 Binary files /dev/null and b/src/images/dialog-close_red.png differ diff --git a/src/images/disk_blue.png b/src/images/disk_blue.png new file mode 100644 index 0000000..1abc0e7 Binary files /dev/null and b/src/images/disk_blue.png differ diff --git a/src/images/document-new_16.png b/src/images/document-new_16.png new file mode 100644 index 0000000..d3661a1 Binary files /dev/null and b/src/images/document-new_16.png differ diff --git a/src/images/document-new_24.png b/src/images/document-new_24.png new file mode 100644 index 0000000..5df5bd4 Binary files /dev/null and b/src/images/document-new_24.png differ diff --git a/src/images/document_add.png b/src/images/document_add.png new file mode 100644 index 0000000..dc06d21 Binary files /dev/null and b/src/images/document_add.png differ diff --git a/src/images/document_add_1.png b/src/images/document_add_1.png new file mode 100644 index 0000000..562efc2 Binary files /dev/null and b/src/images/document_add_1.png differ diff --git a/src/images/document_delete_16.png b/src/images/document_delete_16.png new file mode 100644 index 0000000..f4fb311 Binary files /dev/null and b/src/images/document_delete_16.png differ diff --git a/src/images/document_delete_24.png b/src/images/document_delete_24.png new file mode 100644 index 0000000..8199e63 Binary files /dev/null and b/src/images/document_delete_24.png differ diff --git a/src/images/document_zoom_in.png b/src/images/document_zoom_in.png new file mode 100644 index 0000000..5d46e3e Binary files /dev/null and b/src/images/document_zoom_in.png differ diff --git a/src/images/document_zoom_in_1.png b/src/images/document_zoom_in_1.png new file mode 100644 index 0000000..a73a4bf Binary files /dev/null and b/src/images/document_zoom_in_1.png differ diff --git a/src/images/document_zoom_out.png b/src/images/document_zoom_out.png new file mode 100644 index 0000000..0cb534b Binary files /dev/null and b/src/images/document_zoom_out.png differ diff --git a/src/images/document_zoom_out_1.png b/src/images/document_zoom_out_1.png new file mode 100644 index 0000000..d4efa86 Binary files /dev/null and b/src/images/document_zoom_out_1.png differ diff --git a/src/images/edit-copy_1_16.png b/src/images/edit-copy_1_16.png new file mode 100644 index 0000000..8dd48c4 Binary files /dev/null and b/src/images/edit-copy_1_16.png differ diff --git a/src/images/edit-copy_1_24.png b/src/images/edit-copy_1_24.png new file mode 100644 index 0000000..345b2f1 Binary files /dev/null and b/src/images/edit-copy_1_24.png differ diff --git a/src/images/edit-paste_1_16.png b/src/images/edit-paste_1_16.png new file mode 100644 index 0000000..b0fa070 Binary files /dev/null and b/src/images/edit-paste_1_16.png differ diff --git a/src/images/edit-paste_1_24.png b/src/images/edit-paste_1_24.png new file mode 100644 index 0000000..d131b84 Binary files /dev/null and b/src/images/edit-paste_1_24.png differ diff --git a/src/images/edit-paste_2_24.png b/src/images/edit-paste_2_24.png new file mode 100644 index 0000000..cc8b1bd Binary files /dev/null and b/src/images/edit-paste_2_24.png differ diff --git a/src/images/edit.png b/src/images/edit.png new file mode 100644 index 0000000..083b97c Binary files /dev/null and b/src/images/edit.png differ diff --git a/src/images/edit_control_24.png b/src/images/edit_control_24.png new file mode 100644 index 0000000..c2af048 Binary files /dev/null and b/src/images/edit_control_24.png differ diff --git a/src/images/edit_control_2_24.png b/src/images/edit_control_2_24.png new file mode 100644 index 0000000..18717d4 Binary files /dev/null and b/src/images/edit_control_2_24.png differ diff --git a/src/images/edit_control_3_24.png b/src/images/edit_control_3_24.png new file mode 100644 index 0000000..42ed53d Binary files /dev/null and b/src/images/edit_control_3_24.png differ diff --git a/src/images/edit_cursor.png b/src/images/edit_cursor.png new file mode 100644 index 0000000..21070fb Binary files /dev/null and b/src/images/edit_cursor.png differ diff --git a/src/images/edit_layout.png b/src/images/edit_layout.png new file mode 100644 index 0000000..1f12414 Binary files /dev/null and b/src/images/edit_layout.png differ diff --git a/src/images/edit_layout_2_24.png b/src/images/edit_layout_2_24.png new file mode 100644 index 0000000..23818d3 Binary files /dev/null and b/src/images/edit_layout_2_24.png differ diff --git a/src/images/edit_layout_3_24.png b/src/images/edit_layout_3_24.png new file mode 100644 index 0000000..b000f6f Binary files /dev/null and b/src/images/edit_layout_3_24.png differ diff --git a/src/images/edit_layout_4_24.png b/src/images/edit_layout_4_24.png new file mode 100644 index 0000000..29e1387 Binary files /dev/null and b/src/images/edit_layout_4_24.png differ diff --git a/src/images/edit_pecil2.png b/src/images/edit_pecil2.png new file mode 100644 index 0000000..29fc9a0 Binary files /dev/null and b/src/images/edit_pecil2.png differ diff --git a/src/images/edit_pencil.png b/src/images/edit_pencil.png new file mode 100644 index 0000000..c2b75d9 Binary files /dev/null and b/src/images/edit_pencil.png differ diff --git a/src/images/errors.png b/src/images/errors.png new file mode 100644 index 0000000..d534c53 Binary files /dev/null and b/src/images/errors.png differ diff --git a/src/images/field.png b/src/images/field.png new file mode 100644 index 0000000..3cb6ea6 Binary files /dev/null and b/src/images/field.png differ diff --git a/src/images/first2.png b/src/images/first2.png new file mode 100644 index 0000000..082aecd Binary files /dev/null and b/src/images/first2.png differ diff --git a/src/images/folder.png b/src/images/folder.png new file mode 100644 index 0000000..084c9da Binary files /dev/null and b/src/images/folder.png differ diff --git a/src/images/folder1.png b/src/images/folder1.png new file mode 100644 index 0000000..528229c Binary files /dev/null and b/src/images/folder1.png differ diff --git a/src/images/folder3.png b/src/images/folder3.png new file mode 100644 index 0000000..d857735 Binary files /dev/null and b/src/images/folder3.png differ diff --git a/src/images/function.png b/src/images/function.png new file mode 100644 index 0000000..65186bd Binary files /dev/null and b/src/images/function.png differ diff --git a/src/images/function2.png b/src/images/function2.png new file mode 100644 index 0000000..f346cc2 Binary files /dev/null and b/src/images/function2.png differ diff --git a/src/images/function3.png b/src/images/function3.png new file mode 100644 index 0000000..d6371b9 Binary files /dev/null and b/src/images/function3.png differ diff --git a/src/images/go-next.png b/src/images/go-next.png new file mode 100644 index 0000000..da01acc Binary files /dev/null and b/src/images/go-next.png differ diff --git a/src/images/hlayout.png b/src/images/hlayout.png new file mode 100644 index 0000000..3c9523e Binary files /dev/null and b/src/images/hlayout.png differ diff --git a/src/images/hlayuot_1_24.png b/src/images/hlayuot_1_24.png new file mode 100644 index 0000000..12340fe Binary files /dev/null and b/src/images/hlayuot_1_24.png differ diff --git a/src/images/hlayuot_2_24.png b/src/images/hlayuot_2_24.png new file mode 100644 index 0000000..c648cb2 Binary files /dev/null and b/src/images/hlayuot_2_24.png differ diff --git a/src/images/hlayuot_3_24.png b/src/images/hlayuot_3_24.png new file mode 100644 index 0000000..66cf271 Binary files /dev/null and b/src/images/hlayuot_3_24.png differ diff --git a/src/images/hourglass.png b/src/images/hourglass.png new file mode 100644 index 0000000..2cb94c7 Binary files /dev/null and b/src/images/hourglass.png differ diff --git a/src/images/insert-text_16.png b/src/images/insert-text_16.png new file mode 100644 index 0000000..0a1b7d0 Binary files /dev/null and b/src/images/insert-text_16.png differ diff --git a/src/images/insert-text_1_24.png b/src/images/insert-text_1_24.png new file mode 100644 index 0000000..e5c6841 Binary files /dev/null and b/src/images/insert-text_1_24.png differ diff --git a/src/images/insert-text_24.png b/src/images/insert-text_24.png new file mode 100644 index 0000000..de6c75f Binary files /dev/null and b/src/images/insert-text_24.png differ diff --git a/src/images/last2.png b/src/images/last2.png new file mode 100644 index 0000000..dd0145a Binary files /dev/null and b/src/images/last2.png differ diff --git a/src/images/layuot_create.png b/src/images/layuot_create.png new file mode 100644 index 0000000..095b604 Binary files /dev/null and b/src/images/layuot_create.png differ diff --git a/src/images/layuot_create_24.png b/src/images/layuot_create_24.png new file mode 100644 index 0000000..f8a162a Binary files /dev/null and b/src/images/layuot_create_24.png differ diff --git a/src/images/layuot_delete_24.png b/src/images/layuot_delete_24.png new file mode 100644 index 0000000..a3ef37e Binary files /dev/null and b/src/images/layuot_delete_24.png differ diff --git a/src/images/layuot_move.png b/src/images/layuot_move.png new file mode 100644 index 0000000..922fe74 Binary files /dev/null and b/src/images/layuot_move.png differ diff --git a/src/images/layuot_select.png b/src/images/layuot_select.png new file mode 100644 index 0000000..dabd5fc Binary files /dev/null and b/src/images/layuot_select.png differ diff --git a/src/images/layuot_select_24.png b/src/images/layuot_select_24.png new file mode 100644 index 0000000..f3b4588 Binary files /dev/null and b/src/images/layuot_select_24.png differ diff --git a/src/images/leftLine.png b/src/images/leftLine.png new file mode 100644 index 0000000..e98990b Binary files /dev/null and b/src/images/leftLine.png differ diff --git a/src/images/leftLine1.png b/src/images/leftLine1.png new file mode 100644 index 0000000..cb8c9d1 Binary files /dev/null and b/src/images/leftLine1.png differ diff --git a/src/images/logo.png b/src/images/logo.png new file mode 100644 index 0000000..a466bbb Binary files /dev/null and b/src/images/logo.png differ diff --git a/src/images/logo_100.png b/src/images/logo_100.png new file mode 100644 index 0000000..d626e9f Binary files /dev/null and b/src/images/logo_100.png differ diff --git a/src/images/main.ico b/src/images/main.ico new file mode 100644 index 0000000..7f11705 Binary files /dev/null and b/src/images/main.ico differ diff --git a/src/images/main.png b/src/images/main.png new file mode 100644 index 0000000..216f24a Binary files /dev/null and b/src/images/main.png differ diff --git a/src/images/move_back.png b/src/images/move_back.png new file mode 100644 index 0000000..a913279 Binary files /dev/null and b/src/images/move_back.png differ diff --git a/src/images/move_top_1.png b/src/images/move_top_1.png new file mode 100644 index 0000000..aefcb79 Binary files /dev/null and b/src/images/move_top_1.png differ diff --git a/src/images/new_1_16.png b/src/images/new_1_16.png new file mode 100644 index 0000000..27e02bd Binary files /dev/null and b/src/images/new_1_16.png differ diff --git a/src/images/new_1_24.png b/src/images/new_1_24.png new file mode 100644 index 0000000..efa2da7 Binary files /dev/null and b/src/images/new_1_24.png differ diff --git a/src/images/new_leaf.png b/src/images/new_leaf.png new file mode 100644 index 0000000..59c868a Binary files /dev/null and b/src/images/new_leaf.png differ diff --git a/src/images/new_leaf1.png b/src/images/new_leaf1.png new file mode 100644 index 0000000..d89f8d3 Binary files /dev/null and b/src/images/new_leaf1.png differ diff --git a/src/images/next.png b/src/images/next.png new file mode 100644 index 0000000..f88c881 Binary files /dev/null and b/src/images/next.png differ diff --git a/src/images/next1.png b/src/images/next1.png new file mode 100644 index 0000000..9b3a487 Binary files /dev/null and b/src/images/next1.png differ diff --git a/src/images/next2.png b/src/images/next2.png new file mode 100644 index 0000000..4d2a52c Binary files /dev/null and b/src/images/next2.png differ diff --git a/src/images/noLines.png b/src/images/noLines.png new file mode 100644 index 0000000..9d41db0 Binary files /dev/null and b/src/images/noLines.png differ diff --git a/src/images/noLines1.png b/src/images/noLines1.png new file mode 100644 index 0000000..264044e Binary files /dev/null and b/src/images/noLines1.png differ diff --git a/src/images/paste.png b/src/images/paste.png new file mode 100644 index 0000000..3514130 Binary files /dev/null and b/src/images/paste.png differ diff --git a/src/images/paste1.png b/src/images/paste1.png new file mode 100644 index 0000000..ed5b4bc Binary files /dev/null and b/src/images/paste1.png differ diff --git a/src/images/paste16.png b/src/images/paste16.png new file mode 100644 index 0000000..a4e0a02 Binary files /dev/null and b/src/images/paste16.png differ diff --git a/src/images/paste24.png b/src/images/paste24.png new file mode 100644 index 0000000..bd6fe40 Binary files /dev/null and b/src/images/paste24.png differ diff --git a/src/images/paste_1_24.png b/src/images/paste_1_24.png new file mode 100644 index 0000000..13450d0 Binary files /dev/null and b/src/images/paste_1_24.png differ diff --git a/src/images/pin_green.png b/src/images/pin_green.png new file mode 100644 index 0000000..355510e Binary files /dev/null and b/src/images/pin_green.png differ diff --git a/src/images/prin-preview2.png b/src/images/prin-preview2.png new file mode 100644 index 0000000..bad9ab0 Binary files /dev/null and b/src/images/prin-preview2.png differ diff --git a/src/images/prin-preview_2.png b/src/images/prin-preview_2.png new file mode 100644 index 0000000..6c6c63e Binary files /dev/null and b/src/images/prin-preview_2.png differ diff --git a/src/images/prin-preview_3.png b/src/images/prin-preview_3.png new file mode 100644 index 0000000..370f695 Binary files /dev/null and b/src/images/prin-preview_3.png differ diff --git a/src/images/prin-preview_4_24.png b/src/images/prin-preview_4_24.png new file mode 100644 index 0000000..ec9f55e Binary files /dev/null and b/src/images/prin-preview_4_24.png differ diff --git a/src/images/print.png b/src/images/print.png new file mode 100644 index 0000000..bb65b29 Binary files /dev/null and b/src/images/print.png differ diff --git a/src/images/print2_big.png b/src/images/print2_big.png new file mode 100644 index 0000000..0fdb872 Binary files /dev/null and b/src/images/print2_big.png differ diff --git a/src/images/print_2.png b/src/images/print_2.png new file mode 100644 index 0000000..774ad17 Binary files /dev/null and b/src/images/print_2.png differ diff --git a/src/images/print_2_24.png b/src/images/print_2_24.png new file mode 100644 index 0000000..aeec91f Binary files /dev/null and b/src/images/print_2_24.png differ diff --git a/src/images/print_preview.png b/src/images/print_preview.png new file mode 100644 index 0000000..32a5e02 Binary files /dev/null and b/src/images/print_preview.png differ diff --git a/src/images/print_preview1.png b/src/images/print_preview1.png new file mode 100644 index 0000000..7fc0d31 Binary files /dev/null and b/src/images/print_preview1.png differ diff --git a/src/images/print_preview2.png b/src/images/print_preview2.png new file mode 100644 index 0000000..f196c43 Binary files /dev/null and b/src/images/print_preview2.png differ diff --git a/src/images/prior.png b/src/images/prior.png new file mode 100644 index 0000000..275b99a Binary files /dev/null and b/src/images/prior.png differ diff --git a/src/images/prior1.png b/src/images/prior1.png new file mode 100644 index 0000000..cc71bd5 Binary files /dev/null and b/src/images/prior1.png differ diff --git a/src/images/prior2.png b/src/images/prior2.png new file mode 100644 index 0000000..7af6a9c Binary files /dev/null and b/src/images/prior2.png differ diff --git a/src/images/redo.png b/src/images/redo.png new file mode 100644 index 0000000..6c5e773 Binary files /dev/null and b/src/images/redo.png differ diff --git a/src/images/redo1.png b/src/images/redo1.png new file mode 100644 index 0000000..89d51fb Binary files /dev/null and b/src/images/redo1.png differ diff --git a/src/images/redo_1_16.png b/src/images/redo_1_16.png new file mode 100644 index 0000000..17f7ac0 Binary files /dev/null and b/src/images/redo_1_16.png differ diff --git a/src/images/redo_1_24.png b/src/images/redo_1_24.png new file mode 100644 index 0000000..7ae0543 Binary files /dev/null and b/src/images/redo_1_24.png differ diff --git a/src/images/rightLine.png b/src/images/rightLine.png new file mode 100644 index 0000000..d5d85d4 Binary files /dev/null and b/src/images/rightLine.png differ diff --git a/src/images/rightLine1.png b/src/images/rightLine1.png new file mode 100644 index 0000000..c7b08bd Binary files /dev/null and b/src/images/rightLine1.png differ diff --git a/src/images/save.png b/src/images/save.png new file mode 100644 index 0000000..80204eb Binary files /dev/null and b/src/images/save.png differ diff --git a/src/images/save_1_16.png b/src/images/save_1_16.png new file mode 100644 index 0000000..4971653 Binary files /dev/null and b/src/images/save_1_16.png differ diff --git a/src/images/save_1_24.png b/src/images/save_1_24.png new file mode 100644 index 0000000..621fe37 Binary files /dev/null and b/src/images/save_1_24.png differ diff --git a/src/images/save_as_1_16.png b/src/images/save_as_1_16.png new file mode 100644 index 0000000..772e3f6 Binary files /dev/null and b/src/images/save_as_1_16.png differ diff --git a/src/images/save_as_1_24.png b/src/images/save_as_1_24.png new file mode 100644 index 0000000..7e2e8fe Binary files /dev/null and b/src/images/save_as_1_24.png differ diff --git a/src/images/sendToBack.png b/src/images/sendToBack.png new file mode 100644 index 0000000..dd6de9e Binary files /dev/null and b/src/images/sendToBack.png differ diff --git a/src/images/table.png b/src/images/table.png new file mode 100644 index 0000000..936e4fc Binary files /dev/null and b/src/images/table.png differ diff --git a/src/images/table1.png b/src/images/table1.png new file mode 100644 index 0000000..09e13ad Binary files /dev/null and b/src/images/table1.png differ diff --git a/src/images/text-align-botom.png b/src/images/text-align-botom.png new file mode 100644 index 0000000..1f7f1bc Binary files /dev/null and b/src/images/text-align-botom.png differ diff --git a/src/images/text-align-botom1.png b/src/images/text-align-botom1.png new file mode 100644 index 0000000..8b67f66 Binary files /dev/null and b/src/images/text-align-botom1.png differ diff --git a/src/images/text-align-justify.png b/src/images/text-align-justify.png new file mode 100644 index 0000000..1aa7188 Binary files /dev/null and b/src/images/text-align-justify.png differ diff --git a/src/images/text-align-justify1.png b/src/images/text-align-justify1.png new file mode 100644 index 0000000..69cbb4f Binary files /dev/null and b/src/images/text-align-justify1.png differ diff --git a/src/images/text-align-top.png b/src/images/text-align-top.png new file mode 100644 index 0000000..fe6bbb5 Binary files /dev/null and b/src/images/text-align-top.png differ diff --git a/src/images/text-align-top1.png b/src/images/text-align-top1.png new file mode 100644 index 0000000..b44ed19 Binary files /dev/null and b/src/images/text-align-top1.png differ diff --git a/src/images/text-align-v-center.png b/src/images/text-align-v-center.png new file mode 100644 index 0000000..b505637 Binary files /dev/null and b/src/images/text-align-v-center.png differ diff --git a/src/images/text-align-v-center1.png b/src/images/text-align-v-center1.png new file mode 100644 index 0000000..7b56ffb Binary files /dev/null and b/src/images/text-align-v-center1.png differ diff --git a/src/images/text_align_center.png b/src/images/text_align_center.png new file mode 100644 index 0000000..57beb38 Binary files /dev/null and b/src/images/text_align_center.png differ diff --git a/src/images/text_align_center1.png b/src/images/text_align_center1.png new file mode 100644 index 0000000..d903ecc Binary files /dev/null and b/src/images/text_align_center1.png differ diff --git a/src/images/text_align_left.png b/src/images/text_align_left.png new file mode 100644 index 0000000..6c8fcc1 Binary files /dev/null and b/src/images/text_align_left.png differ diff --git a/src/images/text_align_left1.png b/src/images/text_align_left1.png new file mode 100644 index 0000000..a6ac107 Binary files /dev/null and b/src/images/text_align_left1.png differ diff --git a/src/images/text_align_right.png b/src/images/text_align_right.png new file mode 100644 index 0000000..a150257 Binary files /dev/null and b/src/images/text_align_right.png differ diff --git a/src/images/text_align_right1.png b/src/images/text_align_right1.png new file mode 100644 index 0000000..24bf51b Binary files /dev/null and b/src/images/text_align_right1.png differ diff --git a/src/images/text_bold.png b/src/images/text_bold.png new file mode 100644 index 0000000..889ae80 Binary files /dev/null and b/src/images/text_bold.png differ diff --git a/src/images/text_bold1.png b/src/images/text_bold1.png new file mode 100644 index 0000000..379d525 Binary files /dev/null and b/src/images/text_bold1.png differ diff --git a/src/images/text_italic.png b/src/images/text_italic.png new file mode 100644 index 0000000..8482ac8 Binary files /dev/null and b/src/images/text_italic.png differ diff --git a/src/images/text_italic1.png b/src/images/text_italic1.png new file mode 100644 index 0000000..e8ec97c Binary files /dev/null and b/src/images/text_italic1.png differ diff --git a/src/images/text_underline.png b/src/images/text_underline.png new file mode 100644 index 0000000..90d0df2 Binary files /dev/null and b/src/images/text_underline.png differ diff --git a/src/images/text_underline1.png b/src/images/text_underline1.png new file mode 100644 index 0000000..dfd9e37 Binary files /dev/null and b/src/images/text_underline1.png differ diff --git a/src/images/toBack.png b/src/images/toBack.png new file mode 100644 index 0000000..87300a3 Binary files /dev/null and b/src/images/toBack.png differ diff --git a/src/images/toBottom.png b/src/images/toBottom.png new file mode 100644 index 0000000..e8e8bd3 Binary files /dev/null and b/src/images/toBottom.png differ diff --git a/src/images/toCenter.png b/src/images/toCenter.png new file mode 100644 index 0000000..ebc5df9 Binary files /dev/null and b/src/images/toCenter.png differ diff --git a/src/images/toFront.png b/src/images/toFront.png new file mode 100644 index 0000000..cd4f770 Binary files /dev/null and b/src/images/toFront.png differ diff --git a/src/images/toLeft1.png b/src/images/toLeft1.png new file mode 100644 index 0000000..8277458 Binary files /dev/null and b/src/images/toLeft1.png differ diff --git a/src/images/toRight.png b/src/images/toRight.png new file mode 100644 index 0000000..60d1f0f Binary files /dev/null and b/src/images/toRight.png differ diff --git a/src/images/toSameHeight.png b/src/images/toSameHeight.png new file mode 100644 index 0000000..823f08c Binary files /dev/null and b/src/images/toSameHeight.png differ diff --git a/src/images/toSameWidth.png b/src/images/toSameWidth.png new file mode 100644 index 0000000..272be6b Binary files /dev/null and b/src/images/toSameWidth.png differ diff --git a/src/images/toTop.png b/src/images/toTop.png new file mode 100644 index 0000000..7d4ffbc Binary files /dev/null and b/src/images/toTop.png differ diff --git a/src/images/toVCernter.png b/src/images/toVCernter.png new file mode 100644 index 0000000..bbe5110 Binary files /dev/null and b/src/images/toVCernter.png differ diff --git a/src/images/to_bottom.png b/src/images/to_bottom.png new file mode 100644 index 0000000..00ae931 Binary files /dev/null and b/src/images/to_bottom.png differ diff --git a/src/images/to_bottom_2.png b/src/images/to_bottom_2.png new file mode 100644 index 0000000..1161c42 Binary files /dev/null and b/src/images/to_bottom_2.png differ diff --git a/src/images/to_center.png b/src/images/to_center.png new file mode 100644 index 0000000..edd8a94 Binary files /dev/null and b/src/images/to_center.png differ diff --git a/src/images/to_center_2.png b/src/images/to_center_2.png new file mode 100644 index 0000000..78b4935 Binary files /dev/null and b/src/images/to_center_2.png differ diff --git a/src/images/to_h_center.png b/src/images/to_h_center.png new file mode 100644 index 0000000..0e5b0f6 Binary files /dev/null and b/src/images/to_h_center.png differ diff --git a/src/images/to_h_center_2.png b/src/images/to_h_center_2.png new file mode 100644 index 0000000..30679ff Binary files /dev/null and b/src/images/to_h_center_2.png differ diff --git a/src/images/to_left.png b/src/images/to_left.png new file mode 100644 index 0000000..1427073 Binary files /dev/null and b/src/images/to_left.png differ diff --git a/src/images/to_left_2.png b/src/images/to_left_2.png new file mode 100644 index 0000000..c04d56a Binary files /dev/null and b/src/images/to_left_2.png differ diff --git a/src/images/to_right.png b/src/images/to_right.png new file mode 100644 index 0000000..4b9e5e9 Binary files /dev/null and b/src/images/to_right.png differ diff --git a/src/images/to_right_2.png b/src/images/to_right_2.png new file mode 100644 index 0000000..5ec05c6 Binary files /dev/null and b/src/images/to_right_2.png differ diff --git a/src/images/to_same_height.png b/src/images/to_same_height.png new file mode 100644 index 0000000..db1bb6b Binary files /dev/null and b/src/images/to_same_height.png differ diff --git a/src/images/to_same_height_2.png b/src/images/to_same_height_2.png new file mode 100644 index 0000000..eda1bda Binary files /dev/null and b/src/images/to_same_height_2.png differ diff --git a/src/images/to_same_width.png b/src/images/to_same_width.png new file mode 100644 index 0000000..b339939 Binary files /dev/null and b/src/images/to_same_width.png differ diff --git a/src/images/to_same_width_2.png b/src/images/to_same_width_2.png new file mode 100644 index 0000000..4f1b976 Binary files /dev/null and b/src/images/to_same_width_2.png differ diff --git a/src/images/to_top.png b/src/images/to_top.png new file mode 100644 index 0000000..4e9415f Binary files /dev/null and b/src/images/to_top.png differ diff --git a/src/images/to_top_2.png b/src/images/to_top_2.png new file mode 100644 index 0000000..85bed49 Binary files /dev/null and b/src/images/to_top_2.png differ diff --git a/src/images/topLine.png b/src/images/topLine.png new file mode 100644 index 0000000..132b249 Binary files /dev/null and b/src/images/topLine.png differ diff --git a/src/images/topLine1.png b/src/images/topLine1.png new file mode 100644 index 0000000..a9cda53 Binary files /dev/null and b/src/images/topLine1.png differ diff --git a/src/images/undo.png b/src/images/undo.png new file mode 100644 index 0000000..a0da695 Binary files /dev/null and b/src/images/undo.png differ diff --git a/src/images/undo1.png b/src/images/undo1.png new file mode 100644 index 0000000..805b474 Binary files /dev/null and b/src/images/undo1.png differ diff --git a/src/images/undo_1_16.png b/src/images/undo_1_16.png new file mode 100644 index 0000000..d4835eb Binary files /dev/null and b/src/images/undo_1_16.png differ diff --git a/src/images/undo_1_24.png b/src/images/undo_1_24.png new file mode 100644 index 0000000..d2ce600 Binary files /dev/null and b/src/images/undo_1_24.png differ diff --git a/src/images/value.png b/src/images/value.png new file mode 100644 index 0000000..32660c9 Binary files /dev/null and b/src/images/value.png differ diff --git a/src/images/var1.png b/src/images/var1.png new file mode 100644 index 0000000..c3db99f Binary files /dev/null and b/src/images/var1.png differ diff --git a/src/images/variable.png b/src/images/variable.png new file mode 100644 index 0000000..054cb8d Binary files /dev/null and b/src/images/variable.png differ diff --git a/src/images/variable1.png b/src/images/variable1.png new file mode 100644 index 0000000..3a1d537 Binary files /dev/null and b/src/images/variable1.png differ diff --git a/src/images/vlayout.png b/src/images/vlayout.png new file mode 100644 index 0000000..09ef05c Binary files /dev/null and b/src/images/vlayout.png differ diff --git a/src/images/zoom-in_1_16.png b/src/images/zoom-in_1_16.png new file mode 100644 index 0000000..4ec3c28 Binary files /dev/null and b/src/images/zoom-in_1_16.png differ diff --git a/src/images/zoom-in_1_24.png b/src/images/zoom-in_1_24.png new file mode 100644 index 0000000..9300db4 Binary files /dev/null and b/src/images/zoom-in_1_24.png differ diff --git a/src/images/zoom-in_2_16.png b/src/images/zoom-in_2_16.png new file mode 100644 index 0000000..e41e780 Binary files /dev/null and b/src/images/zoom-in_2_16.png differ diff --git a/src/images/zoom-out_1_16.png b/src/images/zoom-out_1_16.png new file mode 100644 index 0000000..39dc346 Binary files /dev/null and b/src/images/zoom-out_1_16.png differ diff --git a/src/images/zoom-out_1_24.png b/src/images/zoom-out_1_24.png new file mode 100644 index 0000000..01c6965 Binary files /dev/null and b/src/images/zoom-out_1_24.png differ diff --git a/src/images/zoom_in.png b/src/images/zoom_in.png new file mode 100644 index 0000000..71cacec Binary files /dev/null and b/src/images/zoom_in.png differ diff --git a/src/images/zoom_in1.png b/src/images/zoom_in1.png new file mode 100644 index 0000000..ec2d692 Binary files /dev/null and b/src/images/zoom_in1.png differ diff --git a/src/images/zoom_out.png b/src/images/zoom_out.png new file mode 100644 index 0000000..bcd9e3d Binary files /dev/null and b/src/images/zoom_out.png differ diff --git a/src/images/zoom_out1.png b/src/images/zoom_out1.png new file mode 100644 index 0000000..a6beee7 Binary files /dev/null and b/src/images/zoom_out1.png differ diff --git a/src/items/abordertextitem.cpp b/src/items/abordertextitem.cpp new file mode 100644 index 0000000..f322627 --- /dev/null +++ b/src/items/abordertextitem.cpp @@ -0,0 +1,323 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include +#include + +#include "apagedesignintf.h" +#include "abordertextitem.h" +#include "adesignelementsfactory.h" +#include "aglobal.h" +#include "adatasourcemanager.h" +#include "asimpletagparser.h" + +namespace{ + +const QString xmlTag = "TextItem"; + +ArReport::BaseDesignIntf * createTextItem(QObject* owner, ArReport::BaseDesignIntf* parent){ + return new ArReport::TextItem(owner,parent); +} +bool registred = ArReport::DesignElementsFactory::instance().registerCreator(xmlTag, ArReport::ItemAttribs(QObject::tr("Text Item"),"TextItem"), createTextItem); + +} + +namespace ArReport{ + +TextItem::TextItem(QObject *owner, QGraphicsItem *parent) + : ItemDesignIntf(xmlTag,owner,parent),m_spaceBorder(4){ + m_text = new QTextDocument(); + Init(); +} + +TextItem::TextItem(const QString& text, QObject* owner /*= 0*/, QGraphicsItem* parent /*= 0*/) + :ItemDesignIntf(xmlTag, owner,parent),m_spaceBorder(4){ + m_strText = text; + m_text = new QTextDocument(text); + m_text->setHtml(m_strText); + initText(); + Init(); +} + +TextItem::~TextItem() +{ + delete m_text; +} + +void TextItem::paint(QPainter* ppainter, const QStyleOptionGraphicsItem* style, QWidget* widget) { + Q_UNUSED(widget); + Q_UNUSED(style); + + ppainter->save(); + + setupPainter(ppainter); + + if (isSelected()) { + ppainter->setOpacity(0); + ppainter->fillRect(rect(),QBrush(QColor(Qt::white))); + ppainter->setOpacity(1); + } + else ppainter->fillRect(rect(),QBrush(Qt::white)); + + //initText(); + + QSizeF tmpSize = rect().size()-m_textSize;//m_text->size(); + + if ((tmpSize.height()>0) && (m_alignment & Qt::AlignVCenter)) + ppainter->translate(0,tmpSize.height()/2); + + QRegion clipReg=ppainter->clipRegion().xored(ppainter->clipRegion().subtracted(rect().toRect())); + ppainter->setClipRegion(clipReg); + qreal pos=0; + for(QTextBlock it=m_text->begin();it!=m_text->end();it=it.next()){ + for (int i=0;ilineCount();i++){ + pos+=it.layout()->lineAt(i).height(); + it.layout()->lineAt(i).draw(ppainter,QPointF(spaceBorderSize(),0)); + } + } + + ppainter->restore(); + BaseDesignIntf::paint(ppainter, style, widget); +} + +QString TextItem::text() const{ + return m_strText; +} + +void TextItem::Init() +{ + //setFlag(QGraphicsItem::ItemIsMovable); + //setFlag(QGraphicsItem::ItemIsSelectable); + m_autoWidth=NoneAutoWidth; + m_alignment= Qt::AlignLeft|Qt::AlignTop; + m_autoHeight=false; + m_text->setDefaultFont(sceneFont()); + m_textSize=QSizeF(); +} + +void TextItem::setText(QString value) +{ + if (m_strText.compare(value)!=0){ + m_strText=value; + m_text->setHtml(value); + m_text->setTextWidth(width()); + m_textSize=m_text->size(); + if (!isLoading()){ + update(rect()); + } + } +} + +void TextItem::updateItemSize(RenderPass pass, int /*maxHeight*/) +{ + if (isNeedExpandContent()) + expandContent(pass); + initText(); + + if (m_textSize.width()>width() && (m_autoWidth==MaxWordLength)){ + setWidth(m_textSize.width()); + } + if ((m_textSize.height()>height()) && (m_autoHeight) ){ + setHeight(m_textSize.height()+5); + } +} + +void TextItem::updateLayout() +{ + m_layout.setText(text()); + qreal linePos = 0; + m_layout.beginLayout(); + while(true){ + QTextLine line = m_layout.createLine(); + if (!line.isValid()) break; + line.setLineWidth(width()-m_spaceBorder*2); + line.setPosition(QPoint(m_spaceBorder,linePos)); + linePos+=line.height(); + } + m_layout.endLayout(); +} + +bool TextItem::isNeedExpandContent() const +{ + QRegExp rx("$*\\{[^{]*\\}"); + return text().contains(rx); +} + +QString TextItem::expandDataFields(QString context) +{ + DataManager* dm=DataManager::instance(); + QRegExp rx("\\$D\\{[^\\{]*\\}"); + if (context.contains(rx)){ + + while ((rx.indexIn(context))!=-1){ + QString field=rx.cap(0); + field.remove("$D{"); + field.remove("}"); + if (dm->isContainField(field)) { + context.replace(rx.cap(0),dm->fieldData(field).toString()); + } else { + context.replace(rx.cap(0),tr("Field %1 not found").arg(field)); + } + } + } + return context; +} + +void TextItem::initText() +{ + QTextOption to; + to.setAlignment(m_alignment); + to.setWrapMode(QTextOption::WordWrap); + m_text->setDocumentMargin(spaceBorderSize()); + m_text->setDefaultTextOption(to); + m_text->setDefaultFont(sceneFont()); + m_text->setTextWidth(rect().width()); + m_textSize=m_text->size(); +} + +void TextItem::setGeometry(QRectF rect) +{ + BaseDesignIntf::setGeometry(rect); + m_text->setTextWidth(width()); +} + +bool TextItem::isNeedUpdateSize() const +{ + return ((m_textSize.height()>geometry().height()||m_textSize.width()>geometry().width())&& + (autoHeight()||autoWidth())) + || isNeedExpandContent(); +} + +void TextItem::setSpaceBorderSize(int value) +{ + m_spaceBorder=value; + update(rect()); +} + +void TextItem::setAlignment(Qt::Alignment value) +{ + m_alignment=value; + m_layout.setTextOption(QTextOption(m_alignment)); + update(rect()); +} + +void TextItem::expandContent(RenderPass pass) +{ + QString context=text(); + switch(pass){ + case FirstPass: + context=expandDataFields(context); + break; + case SecondPass:; + } + setText(context); +} + +bool TextItem::canBeSliced(int height) const +{ + return height>(m_text->begin().layout()->lineAt(0).height()); +} + +BaseDesignIntf *TextItem::cloneUpperPart(int height, QObject *owner, QGraphicsItem *parent) +{ + int linesHeight=0; + initText(); + QString tmpText=""; + TextItem* upperPart = dynamic_cast(cloneItem(itemMode(),owner,parent)); + + for (QTextBlock it=m_text->begin();it!=m_text->end();it=it.next()){ + for (int i=0;ilineCount();i++){ + linesHeight+=it.layout()->lineAt(i).height(); + if ((linesHeight>height)) {linesHeight-=it.layout()->lineAt(i).height(); goto loop_exit;} + tmpText+=it.text().mid(it.layout()->lineAt(i).textStart(),it.layout()->lineAt(i).textLength()); + } + } + loop_exit: + upperPart->setHeight(linesHeight); + QScopedPointer context(new HtmlContext(m_strText)); + upperPart->setText(context->extendTextByTags(tmpText,0)); + return upperPart; +} + +BaseDesignIntf *TextItem::cloneBottomPart(int height, QObject *owner, QGraphicsItem *parent) +{ + TextItem* bottomPart = dynamic_cast(cloneItem(itemMode(),owner,parent)); + int linesHeight=0; + int curLine=0; + QTextBlock curBlock; + + QString tmpText=""; + + for (curBlock=m_text->begin();curBlock!=m_text->end();curBlock=curBlock.next()){ + for (curLine=0;curLinelineCount();curLine++){ + linesHeight+=curBlock.layout()->lineAt(curLine).height(); + if (linesHeight>height) {goto loop_exit;} + } + } + loop_exit:; + int textPos=0; + for (;curBlock!=m_text->end();curBlock=curBlock.next()){ + for (;curLinelineCount();curLine++){ + if (tmpText=="") textPos= curBlock.layout()->lineAt(curLine).textStart(); + tmpText+=curBlock.text().mid(curBlock.layout()->lineAt(curLine).textStart(), + curBlock.layout()->lineAt(curLine).textLength()); + } + } + QScopedPointer context(new HtmlContext(m_strText)); + bottomPart->setText(context->extendTextByTags(tmpText,textPos)); + return bottomPart; +} + +BaseDesignIntf *TextItem::createSameTypeItem(QObject *owner, QGraphicsItem *parent) +{ + return new TextItem(owner,parent); +} + +BaseDesignIntf *TextItem::cloneEmpty(int height, QObject *owner, QGraphicsItem *parent) +{ + TextItem* empty=dynamic_cast(cloneItem(itemMode(),owner,parent)); + empty->setText(""); + empty->setHeight(height); + return empty; +} + +void TextItem::objectLoadFinished() +{ + ItemDesignIntf::objectLoadFinished(); + initText(); +} + +void TextItem::setTextItemFont(QFont value) +{ + setFont(value); + m_text->setDefaultFont(sceneFont()); +} + +} + diff --git a/src/items/abordertextitem.h b/src/items/abordertextitem.h new file mode 100644 index 0000000..cc9bdee --- /dev/null +++ b/src/items/abordertextitem.h @@ -0,0 +1,110 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef ABORDERTEXTITEM_H +#define ABORDERTEXTITEM_H +#include +#include +#include +#include "aitemdesignintf.h" +#include + +#include + +namespace ArReport { + +class Tag; +class TextItem : public ArReport::ItemDesignIntf { + Q_OBJECT + Q_ENUMS(AutoWidth) + Q_PROPERTY(QString content READ text WRITE setText) + Q_PROPERTY(int margin READ spaceBorderSize WRITE setSpaceBorderSize) + Q_PROPERTY(Qt::Alignment alignment READ alignment() WRITE setAlignment) + Q_PROPERTY(AutoWidth autoWidth READ autoWidth() WRITE setAutoWidth()) + Q_PROPERTY(bool autoHeight READ autoHeight() WRITE setAutoHeight()) + Q_PROPERTY(QFont font READ font() WRITE setTextItemFont()) +public: + + enum AutoWidth{NoneAutoWidth,MaxWordLength,MaxStringLength}; + + void Init(); + TextItem(QObject* owner,QGraphicsItem* parent); + TextItem(const QString& text,QObject* owner = 0, QGraphicsItem* parent = 0); + ~TextItem(); + + void paint(QPainter* ppainter, const QStyleOptionGraphicsItem*, QWidget*); + QString text() const; + void setText(QString value); + + void setSpaceBorderSize(int value); + int spaceBorderSize() const {return m_spaceBorder;} + + void setAlignment(Qt::Alignment value); + Qt::Alignment alignment(){return m_alignment;} + + virtual void setGeometry(QRectF rect); + virtual bool isNeedUpdateSize() const; + virtual void updateItemSize(RenderPass pass, int); + void expandContent(RenderPass pass); + + void setAutoHeight(bool value){m_autoHeight=value;} + bool autoHeight() const {return m_autoHeight;} + + void setAutoWidth(AutoWidth value){m_autoWidth=value;} + AutoWidth autoWidth() const {return m_autoWidth;} + + virtual bool canBeSliced(int height) const; + virtual bool isEmpty() const{return m_text->isEmpty();} + virtual BaseDesignIntf* cloneUpperPart(int height, QObject *owner, QGraphicsItem *parent); + virtual BaseDesignIntf* cloneBottomPart(int height, QObject *owner, QGraphicsItem *parent); + virtual BaseDesignIntf* createSameTypeItem(QObject* owner=0, QGraphicsItem* parent=0); + virtual BaseDesignIntf* cloneEmpty(int height, QObject *owner, QGraphicsItem *parent); + virtual void objectLoadFinished(); + + void setTextItemFont(QFont value); +protected: + void updateLayout(); + bool isNeedExpandContent() const; + QString expandDataFields(QString context); +private: + void initText(); +private: + QString m_strText; + int m_spaceBorder; + QTextLayout m_layout; + QTextDocument* m_text; + Qt::Alignment m_alignment; + bool m_autoHeight; + AutoWidth m_autoWidth; + QSizeF m_textSize; + QFont m_font; +}; + +} +#endif // ABORDERTEXTITEM_H diff --git a/src/items/editors/lrfonteditorwidget.cpp b/src/items/editors/lrfonteditorwidget.cpp new file mode 100644 index 0000000..2fbb96e --- /dev/null +++ b/src/items/editors/lrfonteditorwidget.cpp @@ -0,0 +1,147 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrfonteditorwidget.h" + +namespace LimeReport{ + +FontEditorWidget::FontEditorWidget(ReportDesignWidget *reportEditor, const QString &title, QWidget *parent) + : ItemEditorWidget(reportEditor,title,parent), m_ignoreSlots(false) { + initEditor(); +} + +FontEditorWidget::FontEditorWidget(ReportDesignWidget *reportEditor, QWidget *parent) + :ItemEditorWidget(reportEditor,parent), m_ignoreSlots(false) { + initEditor(); +} + +void FontEditorWidget::setItemEvent(BaseDesignIntf* item) +{ + + QVariant font=item->property("font"); + if (font.isValid()){ + updateValues(font.value()); + setEnabled(true); + } + +} + +void FontEditorWidget::initEditor() +{ + setIconSize(QSize(24,24)); + setAllowedAreas(Qt::TopToolBarArea); + setFloatable(false); + + m_fontNameEditor = new QFontComboBox(this); + m_fontNameEditor->setFontFilters(QFontComboBox::AllFonts); + connect(m_fontNameEditor,SIGNAL(currentFontChanged(QFont)),this,SLOT(slotFontChanged(QFont))); + addWidget(m_fontNameEditor); + + m_fontSizeModel.setStringList(QStringList()<<"6"<<"7"<<"8"<<"9"<<"10"<<"11"<<"12"<<"14"<<"16"<<"18"<<"20"<<"24"<<"28"<<"30"<<"36"<<"48"<<"64"<<"72"); + m_fontSizeEditor = new QComboBox(this); + m_fontSizeEditor->setModel(&m_fontSizeModel); + m_fontSizeEditor->setEditable(true); + connect(m_fontSizeEditor,SIGNAL(currentIndexChanged(QString)),this,SLOT(slotFontSizeChanged(QString))); + addWidget(m_fontSizeEditor); + + addSeparator(); + setEnabled(false); + + m_fontBold = new QAction(tr("Font bold"),this); + m_fontBold->setIcon(QIcon(":/report/images/textBold")); + m_fontBold->setCheckable(true); + connect(m_fontBold,SIGNAL(toggled(bool)),this,SLOT(slotFontAttribsChanged(bool))); + addAction(m_fontBold); + + m_fontItalic = new QAction(tr("Font Italic"),this); + m_fontItalic->setIcon(QIcon(":/report/images/textItalic")); + m_fontItalic->setCheckable(true); + connect(m_fontItalic,SIGNAL(toggled(bool)),this,SLOT(slotFontAttribsChanged(bool))); + addAction(m_fontItalic); + + m_fontUnderline = new QAction(tr("Font Underline"),this); + m_fontUnderline->setIcon(QIcon(":/report/images/textUnderline")); + m_fontUnderline->setCheckable(true); + connect(m_fontUnderline,SIGNAL(toggled(bool)),this,SLOT(slotFontAttribsChanged(bool))); + addAction(m_fontUnderline); + + if (reportEditor()){ + connect(reportEditor(),SIGNAL(itemPropertyChanged(QString,QString,QVariant,QVariant)), + this,SLOT(slotPropertyChanged(QString,QString,QVariant,QVariant))); + } +} + +void FontEditorWidget::updateValues(const QFont& font) +{ + m_ignoreSlots=true; + m_fontNameEditor->setCurrentFont(font); + m_fontSizeEditor->setEditText(QString::number(font.pointSize())); + m_fontBold->setChecked(font.bold()); + m_fontItalic->setChecked(font.italic()); + m_fontUnderline->setChecked(font.underline()); + m_ignoreSlots=false; +} + + +void FontEditorWidget::slotFontChanged(const QFont &font) +{ + if (reportEditor() && !m_ignoreSlots) reportEditor()->setFont(font); +} + +void FontEditorWidget::slotFontSizeChanged(const QString &value) +{ + if (reportEditor() && !m_ignoreSlots){ + QFont resFont(m_fontNameEditor->currentFont()); + resFont.setPointSize(value.toInt()); + reportEditor()->setFont(resFont); + } +} + +void FontEditorWidget::slotFontAttribsChanged(bool) +{ + if (reportEditor()&& !m_ignoreSlots){ + QFont resFont(m_fontNameEditor->currentFont()); + resFont.setBold(m_fontBold->isChecked()); + resFont.setItalic(m_fontItalic->isChecked()); + resFont.setUnderline(m_fontUnderline->isChecked()); + reportEditor()->setFont(resFont); + } +} + +void FontEditorWidget::slotPropertyChanged(const QString &objectName, const QString &property, const QVariant& oldValue, const QVariant& newValue) +{ + Q_UNUSED(oldValue) + Q_UNUSED(newValue) + if (item()&&(item()->objectName()==objectName)&&(property=="font")){ + updateValues(item()->property("font").value()); + } +} + + +} //namespace LimeReport diff --git a/src/items/editors/lrfonteditorwidget.h b/src/items/editors/lrfonteditorwidget.h new file mode 100644 index 0000000..eb7864e --- /dev/null +++ b/src/items/editors/lrfonteditorwidget.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRFONTEDITORWIDGET_H +#define LRFONTEDITORWIDGET_H + +#include +#include +#include +#include + +#include "lrreportdesignwidget.h" +#include "lritemeditorwidget.h" + +namespace LimeReport{ + +class FontEditorWidget :public ItemEditorWidget{ + Q_OBJECT +public: + explicit FontEditorWidget(ReportDesignWidget* reportEditor, const QString &title, QWidget *parent = 0); + explicit FontEditorWidget(ReportDesignWidget* reportEditor, QWidget *parent = 0); +protected: + void setItemEvent(BaseDesignIntf *item); +private slots: + void slotFontChanged(const QFont& font); + void slotFontSizeChanged(const QString& value); + void slotFontAttribsChanged(bool); + void slotPropertyChanged(const QString& objectName, const QString& property, const QVariant &oldValue, const QVariant &newValue); +private: + void initEditor(); + void updateValues(const QFont &font); + + QFontComboBox* m_fontNameEditor; + QComboBox* m_fontSizeEditor; + QStringListModel m_fontSizeModel; + + QAction* m_fontBold; + QAction* m_fontItalic; + QAction* m_fontUnderline; + + bool m_ignoreSlots; + +}; + +} //namespace LimeReport + +#endif // LRFONTEDITORWIDGET_H diff --git a/src/items/editors/lritemeditorwidget.cpp b/src/items/editors/lritemeditorwidget.cpp new file mode 100644 index 0000000..d335697 --- /dev/null +++ b/src/items/editors/lritemeditorwidget.cpp @@ -0,0 +1,91 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lritemeditorwidget.h" + +namespace LimeReport{ + +ItemEditorWidget::ItemEditorWidget(ReportDesignWidget* reportEditor, const QString& title, QWidget* parent) + :QToolBar(title,parent), m_reportEditor(reportEditor), m_item(0), m_page(0) +{ +} + +ItemEditorWidget::ItemEditorWidget(ReportDesignWidget* reportEditor, QWidget* parent) + :QToolBar(parent), m_reportEditor(reportEditor), m_item(0), m_page(0) +{ +} + +ItemEditorWidget::ItemEditorWidget(PageDesignIntf* page, const QString& title, QWidget* parent) + :QToolBar(title,parent), m_reportEditor(0), m_item(0), m_page(page) +{ +} + +ItemEditorWidget::ItemEditorWidget(PageDesignIntf* page, QWidget* parent) + :QToolBar(parent), m_reportEditor(0), m_item(0), m_page(page) +{ +} + +void ItemEditorWidget::setItem(BaseDesignIntf* item) +{ + if (m_item!=item){ + if (m_item) m_item->disconnect(this); + m_item=item; + connect(m_item,SIGNAL(destroyed(QObject*)),this,SLOT(slotItemDestroyed(QObject*))); + connect(m_item,SIGNAL(propertyChanged(QString,QVariant,QVariant)), + this,SLOT(slotPropertyChanged(QString,QVariant,QVariant))); + setEnabled(false); + setItemEvent(item); + } +} + +void ItemEditorWidget::properyChangedEvent(const QString& propertName, const QVariant& oldValue, const QVariant& newValue) +{ + Q_UNUSED(propertName) + Q_UNUSED(oldValue) + Q_UNUSED(newValue) +} + +void ItemEditorWidget::slotItemDestroyed(QObject* item) +{ + if (item==m_item) { + m_item = 0; + setEnabled(false); + } +} + +void ItemEditorWidget::slotPropertyChanged(const QString& propertName, const QVariant& oldValue, const QVariant& newValue) +{ + properyChangedEvent(propertName,oldValue,newValue); +} + +} + + + + diff --git a/src/items/editors/lritemeditorwidget.h b/src/items/editors/lritemeditorwidget.h new file mode 100644 index 0000000..5214756 --- /dev/null +++ b/src/items/editors/lritemeditorwidget.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRITEMEDITORWIDGET_H +#define LRITEMEDITORWIDGET_H + +#include +#include "lrreportdesignwidget.h" + +namespace LimeReport { + +class ItemEditorWidget : public QToolBar +{ + Q_OBJECT +public: + explicit ItemEditorWidget(ReportDesignWidget* reportEditor, const QString &title, QWidget *parent = 0); + explicit ItemEditorWidget(ReportDesignWidget* reportEditor, QWidget *parent = 0); + explicit ItemEditorWidget(PageDesignIntf* page, const QString &title, QWidget *parent = 0); + explicit ItemEditorWidget(PageDesignIntf* page, QWidget *parent = 0); + + void setItem(BaseDesignIntf *item); + void setReportEditor(ReportDesignWidget* editor){m_reportEditor = editor;} +protected: + virtual void setItemEvent(BaseDesignIntf*){} + virtual void properyChangedEvent(const QString& propertName, const QVariant& oldValue, const QVariant& newValue); + BaseDesignIntf* item(){return m_item;} + ReportDesignWidget* reportEditor(){return m_reportEditor;} + PageDesignIntf* page(){return m_page;} +private slots: + void slotItemDestroyed(QObject* item); + void slotPropertyChanged(const QString& propertName, const QVariant& oldValue, const QVariant& newValue); +private: + ReportDesignWidget* m_reportEditor; + BaseDesignIntf* m_item; + PageDesignIntf* m_page; +}; + +} // namespace LimeReport +#endif // LRITEMEDITORWIDGET_H diff --git a/src/items/editors/lritemsaligneditorwidget.cpp b/src/items/editors/lritemsaligneditorwidget.cpp new file mode 100644 index 0000000..e4c681f --- /dev/null +++ b/src/items/editors/lritemsaligneditorwidget.cpp @@ -0,0 +1,171 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lritemsaligneditorwidget.h" + +namespace LimeReport{ + +ItemsAlignmentEditorWidget::ItemsAlignmentEditorWidget(LimeReport::ReportDesignWidget* reportEditor, const QString& title, QWidget* parent) + :QToolBar(title,parent), m_reportEditor(reportEditor), m_page(0) +{ + initEditor(); +} + +ItemsAlignmentEditorWidget::ItemsAlignmentEditorWidget(ReportDesignWidget* reportEditor, QWidget* parent) + :QToolBar(parent), m_reportEditor(reportEditor), m_page(0) +{ + initEditor(); +} + +ItemsAlignmentEditorWidget::ItemsAlignmentEditorWidget(PageDesignIntf* page, const QString& title, QWidget* parent) + :QToolBar(title,parent), m_reportEditor(0), m_page(page) +{ + initEditor(); +} + +ItemsAlignmentEditorWidget::ItemsAlignmentEditorWidget(PageDesignIntf* page, QWidget* parent) + :QToolBar(parent), m_reportEditor(0), m_page(page) +{ + initEditor(); +} + +void ItemsAlignmentEditorWidget::slotBrinToFront() +{ + if (m_reportEditor) m_reportEditor->brinToFront(); + if (m_page) m_page->bringToFront(); +} + +void ItemsAlignmentEditorWidget::slotSendToBack() +{ + if (m_reportEditor) m_reportEditor->sendToBack(); + if (m_page) m_page->sendToBack(); +} + +void ItemsAlignmentEditorWidget::slotAlignToLeft() +{ + if (m_reportEditor) m_reportEditor->alignToLeft(); + if (m_page) m_page->alignToLeft(); +} + +void ItemsAlignmentEditorWidget::slotAlignToRight() +{ + if (m_reportEditor) m_reportEditor->alignToRight(); + if (m_page) m_page->alignToRigth(); +} + +void ItemsAlignmentEditorWidget::slotAlignToVCenter() +{ + if (m_reportEditor) m_reportEditor->alignToVCenter(); + if (m_page) m_page->alignToVCenter(); +} + +void ItemsAlignmentEditorWidget::slotAlignToTop() +{ + if (m_reportEditor) m_reportEditor->alignToTop(); + if (m_page) m_page->alignToTop(); +} + +void ItemsAlignmentEditorWidget::slotAlignToBottom() +{ + if (m_reportEditor) m_reportEditor->alignToBottom(); + if (m_page) m_page->alignToBottom(); +} + +void ItemsAlignmentEditorWidget::slotAlignToHCenter() +{ + if (m_reportEditor) m_reportEditor->alignToHCenter(); + if (m_page) m_page->alignToHCenter(); +} + +void ItemsAlignmentEditorWidget::slotSameHeight() +{ + if (m_reportEditor) m_reportEditor->sameHeight(); + if (m_page) m_page->sameHeight(); +} + +void ItemsAlignmentEditorWidget::slotSameWidth() +{ + if (m_reportEditor) m_reportEditor->sameWidth(); + if (m_page) m_page->sameWidth(); +} + +void ItemsAlignmentEditorWidget::initEditor() +{ + m_bringToFront = new QAction(tr("Bring to top"),this); + m_bringToFront->setIcon(QIcon(":/report/images/bringToTop")); + connect(m_bringToFront,SIGNAL(triggered()),this,SLOT(slotBrinToFront())); + addAction(m_bringToFront); + + m_sendToBack = new QAction(tr("Send to back"),this); + m_sendToBack->setIcon(QIcon(":/report/images/sendToBack")); + connect(m_sendToBack,SIGNAL(triggered()),this,SLOT(slotSendToBack())); + addAction(m_sendToBack); + + m_alignToLeft = new QAction(tr("Align to left"),this); + m_alignToLeft->setIcon(QIcon(":/report/images/alignToLeft")); + connect(m_alignToLeft,SIGNAL(triggered()),this,SLOT(slotAlignToLeft())); + addAction(m_alignToLeft); + + m_alignToRight = new QAction(tr("Align to right"),this); + m_alignToRight->setIcon(QIcon(":/report/images/alignToRight")); + connect(m_alignToRight,SIGNAL(triggered()),this,SLOT(slotAlignToRight())); + addAction(m_alignToRight); + + m_alignToVCenter = new QAction(tr("Align to vertical center"),this); + m_alignToVCenter->setIcon(QIcon(":/report/images/alignToVCenter")); + connect(m_alignToVCenter,SIGNAL(triggered()),this,SLOT(slotAlignToVCenter())); + addAction(m_alignToVCenter); + + m_alignToTop = new QAction(tr("Align to top"),this); + m_alignToTop->setIcon(QIcon(":/report/images/alignToTop")); + connect(m_alignToTop,SIGNAL(triggered()),this,SLOT(slotAlignToTop())); + addAction(m_alignToTop); + + m_alignToBottom = new QAction(tr("Align to bottom"),this); + m_alignToBottom->setIcon(QIcon(":/report/images/alignToBottom")); + connect(m_alignToBottom,SIGNAL(triggered()),this,SLOT(slotAlignToBottom())); + addAction(m_alignToBottom); + + m_alignToHCenter = new QAction(tr("Align to horizontal center"),this); + m_alignToHCenter->setIcon(QIcon(":/report/images/alignToHCenter")); + connect(m_alignToHCenter,SIGNAL(triggered()),this,SLOT(slotAlignToHCenter())); + addAction(m_alignToHCenter); + + m_sameHeight = new QAction(tr("Set same height"),this); + m_sameHeight->setIcon(QIcon(":/report/images/sameHeight")); + connect(m_sameHeight,SIGNAL(triggered()),this,SLOT(slotSameHeight())); + addAction(m_sameHeight); + + m_sameWidth = new QAction(tr("Set same width"),this); + m_sameWidth->setIcon(QIcon(":/report/images/sameWidth")); + connect(m_sameWidth,SIGNAL(triggered()),this,SLOT(slotSameWidth())); + addAction(m_sameWidth); +} + +} //namespace LimeReport diff --git a/src/items/editors/lritemsaligneditorwidget.h b/src/items/editors/lritemsaligneditorwidget.h new file mode 100644 index 0000000..3dda383 --- /dev/null +++ b/src/items/editors/lritemsaligneditorwidget.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRITEMSALIGNEDITORWIDGET_H +#define LRITEMSALIGNEDITORWIDGET_H + +#include "lrreportdesignwidget.h" +#include +#include + +namespace LimeReport{ + +class ItemsAlignmentEditorWidget : public QToolBar +{ + Q_OBJECT +public: + explicit ItemsAlignmentEditorWidget(ReportDesignWidget* reportEditor, const QString &title, QWidget *parent = 0); + explicit ItemsAlignmentEditorWidget(ReportDesignWidget* reportEditor, QWidget *parent = 0); + explicit ItemsAlignmentEditorWidget(PageDesignIntf* page, const QString &title, QWidget *parent = 0); + explicit ItemsAlignmentEditorWidget(PageDesignIntf* page, QWidget *parent = 0); +private slots: + void slotBrinToFront(); + void slotSendToBack(); + void slotAlignToLeft(); + void slotAlignToRight(); + void slotAlignToVCenter(); + void slotAlignToTop(); + void slotAlignToBottom(); + void slotAlignToHCenter(); + void slotSameHeight(); + void slotSameWidth(); +private: + void initEditor(); + ReportDesignWidget* m_reportEditor; + PageDesignIntf* m_page; + + QAction* m_bringToFront; + QAction* m_sendToBack; + QAction* m_alignToLeft; + QAction* m_alignToRight; + QAction* m_alignToVCenter; + QAction* m_alignToTop; + QAction* m_alignToBottom; + QAction* m_alignToHCenter; + QAction* m_sameHeight; + QAction* m_sameWidth; +}; + +} //namespace LimeReport + +#endif // LRITEMSALIGNEDITORWIDGET_H diff --git a/src/items/editors/lritemsborderseditorwidget.cpp b/src/items/editors/lritemsborderseditorwidget.cpp new file mode 100644 index 0000000..4597b06 --- /dev/null +++ b/src/items/editors/lritemsborderseditorwidget.cpp @@ -0,0 +1,154 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lritemsborderseditorwidget.h" +#include + +namespace LimeReport{ + +ItemsBordersEditorWidget::ItemsBordersEditorWidget(ReportDesignWidget* reportEditor, const QString& title, QWidget* parent) + : ItemEditorWidget(reportEditor,title,parent), m_changing(false) +{ + initEditor(); +} + +ItemsBordersEditorWidget::ItemsBordersEditorWidget(ReportDesignWidget* reportEditor, QWidget* parent) + : ItemEditorWidget(reportEditor,parent), m_changing(false) +{ + initEditor(); +} + +void ItemsBordersEditorWidget::setItemEvent(BaseDesignIntf* item) +{ + QVariant borders=item->property("borders"); + if (borders.isValid()){ + updateValues((BaseDesignIntf::BorderLines)borders.toInt()); + setEnabled(true); + } +} + +void ItemsBordersEditorWidget::properyChangedEvent(const QString& property, const QVariant& oldValue, const QVariant& newValue) +{ + Q_UNUSED(oldValue) + if (property == "borders"){ + m_changing = true; + updateValues((BaseDesignIntf::BorderLines)newValue.toInt()); + m_changing = false; + } +} + +void ItemsBordersEditorWidget::noBordesClicked() +{ + if (reportEditor()) + reportEditor()->setBorders(0); + updateValues(0); +} + +void ItemsBordersEditorWidget::allBordesClicked() +{ + int borders = BaseDesignIntf::LeftLine | + BaseDesignIntf::RightLine | + BaseDesignIntf::TopLine | + BaseDesignIntf::BottomLine; + + updateValues((BaseDesignIntf::BorderLines)borders); + if (reportEditor()) + reportEditor()->setBorders((BaseDesignIntf::BorderLines)borders); +} + +void ItemsBordersEditorWidget::buttonClicked(bool) +{ + if (!m_changing&&reportEditor()) + reportEditor()->setBorders(createBorders()); +} + +void ItemsBordersEditorWidget::initEditor() +{ + + m_topLine = new QAction(tr("Top line"),this); + m_topLine->setIcon(QIcon(":/report/images/topLine")); + m_topLine->setCheckable(true); + connect(m_topLine,SIGNAL(toggled(bool)),this,SLOT(buttonClicked(bool))); + addAction(m_topLine); + + m_bottomLine = new QAction(tr("Top line"),this); + m_bottomLine->setIcon(QIcon(":/report/images/bottomLine")); + m_bottomLine->setCheckable(true); + connect(m_bottomLine,SIGNAL(toggled(bool)),this,SLOT(buttonClicked(bool))); + addAction(m_bottomLine); + + m_leftLine = new QAction(tr("Top line"),this); + m_leftLine->setIcon(QIcon(":/report/images/leftLine")); + m_leftLine->setCheckable(true); + connect(m_leftLine,SIGNAL(toggled(bool)),this,SLOT(buttonClicked(bool))); + addAction(m_leftLine); + + m_rightLine = new QAction(tr("Top line"),this); + m_rightLine->setIcon(QIcon(":/report/images/rightLine")); + m_rightLine->setCheckable(true); + connect(m_rightLine,SIGNAL(toggled(bool)),this,SLOT(buttonClicked(bool))); + addAction(m_rightLine); + + addSeparator(); + + m_noLines = new QAction(tr("No borders"),this); + m_noLines->setIcon(QIcon(":/report/images/noLines")); + connect(m_noLines,SIGNAL(triggered()),this,SLOT(noBordesClicked())); + addAction(m_noLines); + + m_allLines = new QAction(tr("All borders"),this); + m_allLines->setIcon(QIcon(":/report/images/allLines")); + connect(m_allLines,SIGNAL(triggered()),this,SLOT(allBordesClicked())); + addAction(m_allLines); + + setEnabled(false); + +} + +void ItemsBordersEditorWidget::updateValues(BaseDesignIntf::BorderLines borders) +{ + m_changing = true; + m_topLine->setChecked(borders&BaseDesignIntf::TopLine); + m_bottomLine->setChecked(borders&BaseDesignIntf::BottomLine); + m_leftLine->setChecked(borders&BaseDesignIntf::LeftLine); + m_rightLine->setChecked(borders&BaseDesignIntf::RightLine); + m_changing = false; +} + +BaseDesignIntf::BorderLines ItemsBordersEditorWidget::createBorders() +{ + int borders = 0; + borders += (m_topLine->isChecked())?BaseDesignIntf::TopLine:0; + borders += (m_bottomLine->isChecked())?BaseDesignIntf::BottomLine:0; + borders += (m_leftLine->isChecked())?BaseDesignIntf::LeftLine:0; + borders += (m_rightLine->isChecked())?BaseDesignIntf::RightLine:0; + return (BaseDesignIntf::BorderLines)borders; +} + +} //namespace LimeReport diff --git a/src/items/editors/lritemsborderseditorwidget.h b/src/items/editors/lritemsborderseditorwidget.h new file mode 100644 index 0000000..296107e --- /dev/null +++ b/src/items/editors/lritemsborderseditorwidget.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRITEMSBORDERSEDITORWIDGET_H +#define LRITEMSBORDERSEDITORWIDGET_H + +#include +#include "lrreportdesignwidget.h" +#include "lritemeditorwidget.h" + +namespace LimeReport{ + +class ItemsBordersEditorWidget : public ItemEditorWidget +{ + Q_OBJECT +public: + explicit ItemsBordersEditorWidget(ReportDesignWidget* reportEditor, const QString &title, QWidget *parent = 0); + explicit ItemsBordersEditorWidget(ReportDesignWidget* reportEditor, QWidget *parent = 0); +private slots: + void noBordesClicked(); + void allBordesClicked(); + void buttonClicked(bool); +protected: + void setItemEvent(BaseDesignIntf *item); + void properyChangedEvent(const QString &property, const QVariant &oldValue, const QVariant &newValue); +private: + void initEditor(); + void updateValues(BaseDesignIntf::BorderLines borders); + BaseDesignIntf::BorderLines createBorders(); + QAction* m_noLines; + QAction* m_leftLine; + QAction* m_rightLine; + QAction* m_topLine; + QAction* m_bottomLine; + QAction* m_allLines; + bool m_changing; +}; + +}//namespace LimeReport + +#endif // LRITEMSBORDERSEDITORWIDGET_H diff --git a/src/items/editors/lrtextalignmenteditorwidget.cpp b/src/items/editors/lrtextalignmenteditorwidget.cpp new file mode 100644 index 0000000..652f678 --- /dev/null +++ b/src/items/editors/lrtextalignmenteditorwidget.cpp @@ -0,0 +1,190 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrtextalignmenteditorwidget.h" + +namespace LimeReport{ + +TextAlignmentEditorWidget::TextAlignmentEditorWidget(ReportDesignWidget *reportEditor, const QString &title, QWidget *parent) + :ItemEditorWidget(reportEditor,title,parent), m_textAttibutesIsChanging(false) +{ + initEditor(); +} + +TextAlignmentEditorWidget::TextAlignmentEditorWidget(ReportDesignWidget *reportEditor, QWidget *parent) + :ItemEditorWidget(reportEditor,parent), m_textAttibutesIsChanging(false) +{ + initEditor(); +} + +TextAlignmentEditorWidget::TextAlignmentEditorWidget(PageDesignIntf* page, const QString& title, QWidget* parent) + :ItemEditorWidget(page,title,parent), m_textAttibutesIsChanging(false) +{ + initEditor(); +} + +TextAlignmentEditorWidget::TextAlignmentEditorWidget(PageDesignIntf* page, QWidget* parent) + :ItemEditorWidget(page,parent), m_textAttibutesIsChanging(false) +{ + initEditor(); +} + +void TextAlignmentEditorWidget::setItemEvent(BaseDesignIntf *item) +{ + QVariant align=item->property("alignment"); + if (align.isValid()){ + updateValues(Qt::Alignment(align.value())); + setEnabled(true); + } +} + +void TextAlignmentEditorWidget::initEditor() +{ + m_textAliginLeft = new QAction(tr("Text align left"),this); + m_textAliginLeft->setIcon(QIcon(":/report/images/textAlignHLeft")); + m_textAliginLeft->setCheckable(true); + connect(m_textAliginLeft,SIGNAL(toggled(bool)),this,SLOT(slotTextHAttribsChanged(bool))); + addAction(m_textAliginLeft); + + m_textAliginHCenter = new QAction(tr("Text align center"),this); + m_textAliginHCenter->setIcon(QIcon(":/report/images/textAlignHCenter")); + m_textAliginHCenter->setCheckable(true); + connect(m_textAliginHCenter,SIGNAL(toggled(bool)),this,SLOT(slotTextHAttribsChanged(bool))); + addAction(m_textAliginHCenter); + + m_textAliginRight = new QAction(tr("Text align right"),this); + m_textAliginRight->setIcon(QIcon(":/report/images/textAlignHRight")); + m_textAliginRight->setCheckable(true); + connect(m_textAliginRight,SIGNAL(toggled(bool)),this,SLOT(slotTextHAttribsChanged(bool))); + addAction(m_textAliginRight); + + m_textAliginJustify = new QAction(tr("Text align justify"),this); + m_textAliginJustify->setIcon(QIcon(":/report/images/textAlignHJustify")); + m_textAliginJustify->setCheckable(true); + connect(m_textAliginJustify,SIGNAL(toggled(bool)),this,SLOT(slotTextHAttribsChanged(bool))); + addAction(m_textAliginJustify); + + addSeparator(); + + m_textAliginTop = new QAction(tr("Text align top"),this); + m_textAliginTop->setIcon(QIcon(":/report/images/textAlignVTop")); + m_textAliginTop->setCheckable(true); + connect(m_textAliginTop,SIGNAL(toggled(bool)),this,SLOT(slotTextVAttribsChanged(bool))); + addAction(m_textAliginTop); + + m_textAliginVCenter = new QAction(tr("Text align center"),this); + m_textAliginVCenter->setIcon(QIcon(":/report/images/textAlignVCenter")); + m_textAliginVCenter->setCheckable(true); + connect(m_textAliginVCenter,SIGNAL(toggled(bool)),this,SLOT(slotTextVAttribsChanged(bool))); + addAction(m_textAliginVCenter); + + m_textAliginBottom = new QAction(tr("Text align bottom"),this); + m_textAliginBottom->setIcon(QIcon(":/report/images/textAlignVBottom")); + m_textAliginBottom->setCheckable(true); + connect(m_textAliginBottom,SIGNAL(toggled(bool)),this,SLOT(slotTextVAttribsChanged(bool))); + addAction(m_textAliginBottom); + + if (reportEditor()){ + connect(reportEditor(),SIGNAL(itemPropertyChanged(QString,QString,QVariant,QVariant)), + this,SLOT(slotPropertyChanged(QString,QString,QVariant,QVariant))); + } + if (page()){ + connect(page(),SIGNAL(itemPropertyChanged(QString,QString,QVariant,QVariant)), + this,SLOT(slotPropertyChanged(QString,QString,QVariant,QVariant))); + } + setEnabled(false); +} + +void TextAlignmentEditorWidget::updateValues(const Qt::Alignment &align) +{ + m_textAttibutesIsChanging=true; + m_textAliginLeft->setChecked((align & Qt::AlignLeft)==Qt::AlignLeft); + m_textAliginRight->setChecked((align & Qt::AlignRight)==Qt::AlignRight); + m_textAliginHCenter->setChecked((align & Qt::AlignHCenter)==Qt::AlignHCenter); + m_textAliginJustify->setChecked((align & Qt::AlignJustify)==Qt::AlignJustify); + m_textAliginTop->setChecked((align & Qt::AlignTop)==Qt::AlignTop); + m_textAliginVCenter->setChecked((align & Qt::AlignVCenter)==Qt::AlignVCenter); + m_textAliginBottom->setChecked((align & Qt::AlignBottom)==Qt::AlignBottom); + m_textAttibutesIsChanging=false; +} + +Qt::Alignment TextAlignmentEditorWidget::createAlignment() +{ + Qt::Alignment align = 0 ; + if (m_textAliginLeft->isChecked()) align |= Qt::AlignLeft; + if (m_textAliginHCenter->isChecked()) align |= Qt::AlignHCenter; + if (m_textAliginRight->isChecked()) align |= Qt::AlignRight; + if (m_textAliginJustify->isChecked()) align |= Qt::AlignJustify; + if (m_textAliginTop->isChecked()) align |= Qt::AlignTop; + if (m_textAliginVCenter->isChecked()) align |= Qt::AlignVCenter; + if (m_textAliginBottom->isChecked()) align |= Qt::AlignBottom; + return align; +} + +void TextAlignmentEditorWidget::slotTextHAttribsChanged(bool) +{ + if (m_textAttibutesIsChanging) return; + m_textAttibutesIsChanging = true; + + m_textAliginLeft->setChecked(sender()==m_textAliginLeft); + m_textAliginHCenter->setChecked(sender()==m_textAliginHCenter); + m_textAliginRight->setChecked(sender()==m_textAliginRight); + m_textAliginJustify->setChecked(sender()==m_textAliginJustify); + + if (reportEditor()) reportEditor()->setTextAlign(createAlignment()); + if (page()) page()->setTextAlign(createAlignment()); + m_textAttibutesIsChanging = false; +} + +void TextAlignmentEditorWidget::slotTextVAttribsChanged(bool) +{ + if (m_textAttibutesIsChanging) return; + m_textAttibutesIsChanging = true; + + m_textAliginTop->setChecked(sender()==m_textAliginTop); + m_textAliginVCenter->setChecked(sender()==m_textAliginVCenter); + m_textAliginBottom->setChecked(sender()==m_textAliginBottom); + + if (reportEditor()) reportEditor()->setTextAlign(createAlignment()); + if (page()) page()->setTextAlign(createAlignment()); + m_textAttibutesIsChanging = false; +} + +void TextAlignmentEditorWidget::slotPropertyChanged(const QString &objectName, const QString &property, const QVariant &oldValue, const QVariant &newValue) +{ + Q_UNUSED(oldValue) + Q_UNUSED(newValue) + + if (item()&&(item()->objectName()==objectName)&&(property=="alignment")){ + updateValues(Qt::Alignment(item()->property("alignment").value())); + } +} + + +} //namespace LimeReport diff --git a/src/items/editors/lrtextalignmenteditorwidget.h b/src/items/editors/lrtextalignmenteditorwidget.h new file mode 100644 index 0000000..93fd39d --- /dev/null +++ b/src/items/editors/lrtextalignmenteditorwidget.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRTEXTALIGNMENTEDITORWIDGET_H +#define LRTEXTALIGNMENTEDITORWIDGET_H + +#include "lrreportdesignwidget.h" +#include "lritemeditorwidget.h" +#include +#include + +namespace LimeReport{ + +class TextAlignmentEditorWidget:public ItemEditorWidget +{ + Q_OBJECT +public: + explicit TextAlignmentEditorWidget(ReportDesignWidget* reportEditor, const QString &title, QWidget *parent = 0); + explicit TextAlignmentEditorWidget(ReportDesignWidget* reportEditor, QWidget *parent = 0); + explicit TextAlignmentEditorWidget(PageDesignIntf* page, const QString &title, QWidget *parent = 0); + explicit TextAlignmentEditorWidget(PageDesignIntf* page, QWidget *parent = 0); +protected: + void setItemEvent(BaseDesignIntf *item); +private: + void initEditor(); + void updateValues(const Qt::Alignment& align); + Qt::Alignment createAlignment(); +private slots: + void slotTextHAttribsChanged(bool); + void slotTextVAttribsChanged(bool); + void slotPropertyChanged(const QString& objectName, const QString& property, const QVariant &oldValue, const QVariant &newValue); +private: + bool m_textAttibutesIsChanging; + + QAction* m_textAliginLeft; + QAction* m_textAliginRight; + QAction* m_textAliginHCenter; + QAction* m_textAliginJustify; + QAction* m_textAliginTop; + QAction* m_textAliginBottom; + QAction* m_textAliginVCenter; + +}; + +} //namespace LimeReport + +#endif // LRTEXTALIGNMENTEDITORWIDGET_H diff --git a/src/items/images/Control-Edit Box.png b/src/items/images/Control-Edit Box.png new file mode 100644 index 0000000..ea0fb75 Binary files /dev/null and b/src/items/images/Control-Edit Box.png differ diff --git a/src/items/images/DataBand.png b/src/items/images/DataBand.png new file mode 100644 index 0000000..680acb5 Binary files /dev/null and b/src/items/images/DataBand.png differ diff --git a/src/items/images/DataBand16.png b/src/items/images/DataBand16.png new file mode 100644 index 0000000..e608b3b Binary files /dev/null and b/src/items/images/DataBand16.png differ diff --git a/src/items/images/GroupFooter16.png b/src/items/images/GroupFooter16.png new file mode 100644 index 0000000..aac7027 Binary files /dev/null and b/src/items/images/GroupFooter16.png differ diff --git a/src/items/images/GroupHeader16.png b/src/items/images/GroupHeader16.png new file mode 100644 index 0000000..c9a5c46 Binary files /dev/null and b/src/items/images/GroupHeader16.png differ diff --git a/src/items/images/PageFooter.png b/src/items/images/PageFooter.png new file mode 100644 index 0000000..847d4ec Binary files /dev/null and b/src/items/images/PageFooter.png differ diff --git a/src/items/images/PageFooter16.png b/src/items/images/PageFooter16.png new file mode 100644 index 0000000..134d91c Binary files /dev/null and b/src/items/images/PageFooter16.png differ diff --git a/src/items/images/PageHeader.png b/src/items/images/PageHeader.png new file mode 100644 index 0000000..afb768f Binary files /dev/null and b/src/items/images/PageHeader.png differ diff --git a/src/items/images/PageHeader16.png b/src/items/images/PageHeader16.png new file mode 100644 index 0000000..6c75436 Binary files /dev/null and b/src/items/images/PageHeader16.png differ diff --git a/src/items/images/ReportFooter.png b/src/items/images/ReportFooter.png new file mode 100644 index 0000000..da8923f Binary files /dev/null and b/src/items/images/ReportFooter.png differ diff --git a/src/items/images/ReportFooter16.png b/src/items/images/ReportFooter16.png new file mode 100644 index 0000000..33e923d Binary files /dev/null and b/src/items/images/ReportFooter16.png differ diff --git a/src/items/images/ReportHeader.png b/src/items/images/ReportHeader.png new file mode 100644 index 0000000..3bbd065 Binary files /dev/null and b/src/items/images/ReportHeader.png differ diff --git a/src/items/images/ReportHeader16.png b/src/items/images/ReportHeader16.png new file mode 100644 index 0000000..3d38af3 Binary files /dev/null and b/src/items/images/ReportHeader16.png differ diff --git a/src/items/images/ReportPage.png b/src/items/images/ReportPage.png new file mode 100644 index 0000000..4aaf803 Binary files /dev/null and b/src/items/images/ReportPage.png differ diff --git a/src/items/images/ReportPage16.png b/src/items/images/ReportPage16.png new file mode 100644 index 0000000..e9b46b2 Binary files /dev/null and b/src/items/images/ReportPage16.png differ diff --git a/src/items/images/SubDetailBand16.png b/src/items/images/SubDetailBand16.png new file mode 100644 index 0000000..64cbe2f Binary files /dev/null and b/src/items/images/SubDetailBand16.png differ diff --git a/src/items/images/SubDetailFooterBand16.png b/src/items/images/SubDetailFooterBand16.png new file mode 100644 index 0000000..3504ea3 Binary files /dev/null and b/src/items/images/SubDetailFooterBand16.png differ diff --git a/src/items/images/SubDetailHeaderBand16.png b/src/items/images/SubDetailHeaderBand16.png new file mode 100644 index 0000000..7d1c0b9 Binary files /dev/null and b/src/items/images/SubDetailHeaderBand16.png differ diff --git a/src/items/images/addBand1.png b/src/items/images/addBand1.png new file mode 100644 index 0000000..b2941ff Binary files /dev/null and b/src/items/images/addBand1.png differ diff --git a/src/items/images/barcode2.png b/src/items/images/barcode2.png new file mode 100644 index 0000000..328a2ac Binary files /dev/null and b/src/items/images/barcode2.png differ diff --git a/src/items/images/hlayout.png b/src/items/images/hlayout.png new file mode 100644 index 0000000..3c9523e Binary files /dev/null and b/src/items/images/hlayout.png differ diff --git a/src/items/images/hlayuot_3_24.png b/src/items/images/hlayuot_3_24.png new file mode 100644 index 0000000..66cf271 Binary files /dev/null and b/src/items/images/hlayuot_3_24.png differ diff --git a/src/items/images/imageItem.png b/src/items/images/imageItem.png new file mode 100644 index 0000000..8705346 Binary files /dev/null and b/src/items/images/imageItem.png differ diff --git a/src/items/images/imageItem1.png b/src/items/images/imageItem1.png new file mode 100644 index 0000000..4685622 Binary files /dev/null and b/src/items/images/imageItem1.png differ diff --git a/src/items/images/imageItem2.png b/src/items/images/imageItem2.png new file mode 100644 index 0000000..02cda78 Binary files /dev/null and b/src/items/images/imageItem2.png differ diff --git a/src/items/images/insert-text.png b/src/items/images/insert-text.png new file mode 100644 index 0000000..8cdff85 Binary files /dev/null and b/src/items/images/insert-text.png differ diff --git a/src/items/images/insert-text_1.png b/src/items/images/insert-text_1.png new file mode 100644 index 0000000..86741ea Binary files /dev/null and b/src/items/images/insert-text_1.png differ diff --git a/src/items/images/insert-text_2.png b/src/items/images/insert-text_2.png new file mode 100644 index 0000000..c1a6403 Binary files /dev/null and b/src/items/images/insert-text_2.png differ diff --git a/src/items/images/insert-text_3.png b/src/items/images/insert-text_3.png new file mode 100644 index 0000000..f278dd4 Binary files /dev/null and b/src/items/images/insert-text_3.png differ diff --git a/src/items/images/insert-text_5.png b/src/items/images/insert-text_5.png new file mode 100644 index 0000000..e745fbd Binary files /dev/null and b/src/items/images/insert-text_5.png differ diff --git a/src/items/images/settings.png b/src/items/images/settings.png new file mode 100644 index 0000000..9003698 Binary files /dev/null and b/src/items/images/settings.png differ diff --git a/src/items/images/settings2.png b/src/items/images/settings2.png new file mode 100644 index 0000000..8c53fe4 Binary files /dev/null and b/src/items/images/settings2.png differ diff --git a/src/items/images/shape2.png b/src/items/images/shape2.png new file mode 100644 index 0000000..c2bf427 Binary files /dev/null and b/src/items/images/shape2.png differ diff --git a/src/items/images/shape4.png b/src/items/images/shape4.png new file mode 100644 index 0000000..cc74953 Binary files /dev/null and b/src/items/images/shape4.png differ diff --git a/src/items/images/shape5.png b/src/items/images/shape5.png new file mode 100644 index 0000000..8454cbe Binary files /dev/null and b/src/items/images/shape5.png differ diff --git a/src/items/items.qrc b/src/items/items.qrc new file mode 100644 index 0000000..86b8d74 --- /dev/null +++ b/src/items/items.qrc @@ -0,0 +1,37 @@ + + + images/insert-text.png + images/barcode2.png + images/imageItem.png + images/shape2.png + images/shape4.png + images/insert-text_2.png + images/insert-text_3.png + images/hlayout.png + images/insert-text_5.png + images/shape5.png + images/imageItem1.png + images/imageItem2.png + images/settings.png + images/settings2.png + images/hlayuot_3_24.png + images/addBand1.png + images/DataBand.png + images/PageHeader.png + images/PageFooter.png + images/ReportHeader.png + images/ReportFooter.png + images/ReportPage.png + images/PageFooter16.png + images/PageHeader16.png + images/ReportFooter16.png + images/ReportHeader16.png + images/SubDetailBand16.png + images/SubDetailFooterBand16.png + images/SubDetailHeaderBand16.png + images/DataBand16.png + images/GroupFooter16.png + images/GroupHeader16.png + images/ReportPage16.png + + diff --git a/src/items/lralignpropitem.cpp b/src/items/lralignpropitem.cpp new file mode 100644 index 0000000..b859d1d --- /dev/null +++ b/src/items/lralignpropitem.cpp @@ -0,0 +1,165 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lralignpropitem.h" +#include "objectinspector/propertyItems/lrenumpropitem.h" +#include "objectinspector/editors/lrcomboboxeditor.h" +#include "lrtextitem.h" + +namespace{ + LimeReport::ObjectPropItem * createAlignItem( + QObject *object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly + ){ + return new LimeReport::AlignmentPropItem(object, objects, name, displayName, data, parent, readonly); + } + + bool registred = LimeReport::ObjectPropFactory::instance().registerCreator( + LimeReport::APropIdent("alignment","LimeReport::TextItem"), + QObject::tr("alignment"), + createAlignItem + ); +} + +namespace LimeReport{ + +QString AlignmentPropItem::associateValue(int value, const AlignMap* map) const +{ + QString result; + QMap::const_iterator it = map->constBegin(); + for(;it!= map->constEnd();++it){ + if ((value & it.value())) { + if (result.isEmpty()) result+=it.key(); + else result=result+" | "+it.key(); + } + } + return result; +} + +AlignmentPropItem::AlignmentPropItem(QObject *object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value, ObjectPropItem *parent, bool readonly) + :ObjectPropItem(object, objects, name,displayName,value,parent,readonly) +{ + + m_horizMap.insert(tr("Left"),Qt::AlignLeft); + m_horizMap.insert(tr("Right"),Qt::AlignRight); + m_horizMap.insert(tr("Center"),Qt::AlignHCenter); + m_horizMap.insert(tr("Justify"),Qt::AlignJustify); + + m_vertMap.insert(tr("Top"),Qt::AlignTop); + m_vertMap.insert(tr("Center"),Qt::AlignVCenter); + m_vertMap.insert(tr("Botom"),Qt::AlignBottom); + + m_horizEditor = new AlignmentItemEditor(object, objects, name,tr("horizontal"),value.toInt(),this,false,m_horizMap); + m_vertEditor = new AlignmentItemEditor(object, objects, name,tr("vertical"), value.toInt(),this,false,m_vertMap); + + this->appendItem(m_horizEditor); + this->appendItem(m_vertEditor); +} + +QString AlignmentPropItem::displayValue() const +{ + return associateValue(propertyValue().toInt(),&m_horizMap)+" | "+ + associateValue(propertyValue().toInt(),&m_vertMap); +} + +void AlignmentPropItem::setPropertyValue(QVariant value) +{ + m_horizEditor->setPropertyValue(value); + m_vertEditor->setPropertyValue(value); + ObjectPropItem::setPropertyValue(value); +} + +AlignmentItemEditor::AlignmentItemEditor(QObject *object, ObjectsList* objects, const QString &name, const QString &displayName, const QVariant &value, ObjectPropItem *parent, + bool readonly, AlignMap acceptableValues) + :ObjectPropItem(object, objects, name, displayName, value, parent, readonly),m_acceptableValues(acceptableValues) +{ + if (! extractAcceptableValue(value.toInt()).isEmpty()) + setPropertyValue(extractAcceptableValue(value.toInt())[0]); + else setPropertyValue(0); +} + +void AlignmentItemEditor::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index) +{ + int flags = object()->property(propertyName().toLatin1()).toInt(); + int align = m_acceptableValues.value(qobject_cast(propertyEditor)->text()); + flags=clearAcceptableValues(flags) | align; + object()->setProperty(propertyName().toLatin1(),flags); + foreach(QObject* item,*objects()){item->setProperty(propertyName().toLatin1(),flags);} + parent()->setPropertyValue(flags); + model->setData(index,align); +} + +QVector AlignmentItemEditor::extractAcceptableValue(int flags) +{ + QVector result; + AlignMap::const_iterator it = m_acceptableValues.constBegin(); + for (;it != m_acceptableValues.constEnd();++it) + { + if (flags & it.value()) result<addItems(enumValues); + return editor; +} + +void AlignmentItemEditor::setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const +{ + ComboBoxEditor *editor=qobject_cast(propertyEditor); + editor->setTextValue(m_acceptableValues.key(Qt::Alignment(propertyValue().toInt()))); +} + +QString AlignmentItemEditor::displayValue() const +{ + return m_acceptableValues.key(Qt::Alignment(propertyValue().toInt())); +} + +void AlignmentItemEditor::setPropertyValue(QVariant value) +{ + ObjectPropItem::setPropertyValue(extractAcceptableValue(value.toInt())[0]); +} + +} diff --git a/src/items/lralignpropitem.h b/src/items/lralignpropitem.h new file mode 100644 index 0000000..36a0bd7 --- /dev/null +++ b/src/items/lralignpropitem.h @@ -0,0 +1,80 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRALIGNPROPITEM_H +#define LRALIGNPROPITEM_H + +#include "lrobjectpropitem.h" +#include "objectinspector/propertyItems/lrenumpropitem.h" + +namespace LimeReport{ + +typedef QMap AlignMap; + +class AlignmentItemEditor; + +class AlignmentPropItem : public ObjectPropItem +{ + Q_OBJECT +public: + AlignmentPropItem():ObjectPropItem(){} + AlignmentPropItem(QObject *object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value, ObjectPropItem* parent, bool readonly=true); + QString displayValue() const; + void setPropertyValue(QVariant value); +private: + AlignMap m_vertMap; + AlignMap m_horizMap; + AlignmentItemEditor* m_horizEditor; + AlignmentItemEditor* m_vertEditor; + QString associateValue(int value, const AlignMap *map) const; +}; + +class AlignmentItemEditor : public ObjectPropItem +{ + Q_OBJECT +public: + AlignmentItemEditor():ObjectPropItem(){} + AlignmentItemEditor(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value, ObjectPropItem* parent, bool readonly, + AlignMap acceptableValues); + void setModelData(QWidget * propertyEditor, QAbstractItemModel * model, const QModelIndex & index); + void setPropertyEditorData(QWidget * propertyEditor, const QModelIndex &) const; + QWidget* createProperyEditor(QWidget *parent) const; + QString displayValue() const; + void setPropertyValue(QVariant value); +protected: + QVector extractAcceptableValue(int flags); + int clearAcceptableValues(int flags); + AlignMap acceptableValues() const {return m_acceptableValues;} +private: + AlignMap m_acceptableValues; +}; + + +} +#endif // LRALIGNPROPITEM_H diff --git a/src/items/lrbarcodeitem.cpp b/src/items/lrbarcodeitem.cpp new file mode 100644 index 0000000..5647c21 --- /dev/null +++ b/src/items/lrbarcodeitem.cpp @@ -0,0 +1,248 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrbarcodeitem.h" +#include "lrdesignelementsfactory.h" +#include "qzint.h" +#include "lrglobal.h" + +namespace{ + +const QString xmlTag = "BarcodeItem"; + +LimeReport::BaseDesignIntf * createBarcodeItem(QObject* owner, LimeReport::BaseDesignIntf* parent){ + return new LimeReport::BarcodeItem(owner,parent); +} +bool registred = LimeReport::DesignElementsFactory::instance().registerCreator(xmlTag, LimeReport::ItemAttribs(QObject::tr("Barcode Item"),"Item"), createBarcodeItem); + +} + +namespace LimeReport{ + +BarcodeItem::BarcodeItem(QObject* owner,QGraphicsItem* parent) + : ContentItemDesignIntf(xmlTag,owner,parent),m_designTestValue("1"), m_barcodeType(CODE128), + m_foregroundColor(Qt::black), m_backgroundColor(Qt::white), m_whitespace(10), m_angle(Angle0), + m_barcodeWidth(0), m_securityLevel(0), m_pdf417CodeWords(928) +{} + +BarcodeItem::~BarcodeItem() +{} + +BaseDesignIntf *BarcodeItem::createSameTypeItem(QObject *owner, QGraphicsItem *parent) +{ + return new BarcodeItem(owner,parent); +} + +void BarcodeItem::paint(QPainter *ppainter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + ppainter->save(); + Zint::QZint bc; + if (itemMode() & DesignMode) bc.setText(m_designTestValue); + else bc.setText(m_content); + bc.setSymbol(m_barcodeType); + bc.setWhitespace(m_whitespace); + bc.setFgColor(m_foregroundColor); + bc.setBgColor(m_backgroundColor); + bc.setWidth(m_barcodeWidth); + bc.setSecurityLevel(m_securityLevel); + bc.setPdf417CodeWords(m_pdf417CodeWords); + + if (isSelected()) ppainter->setOpacity(SELECTION_OPACITY); + + QRectF bcRect; + + switch (m_angle) { + case Angle0: + bcRect = rect(); + break; + case Angle90: + ppainter->translate(width(),0); + ppainter->rotate(90); + bcRect = QRectF(0,0,height(),width()); + break; + case Angle180: + bcRect = rect(); + ppainter->translate(width(),height()); + ppainter->rotate(180); + break; + case Angle270: + ppainter->translate(0,height()); + ppainter->rotate(270); + bcRect = QRectF(0,0,height(),width()); + break; + } + + bc.render(*ppainter,bcRect,Zint::QZint::KeepAspectRatio); + ppainter->restore(); + ItemDesignIntf::paint(ppainter,option,widget); +} + +void BarcodeItem::setContent(const QString &content) +{ + if (m_content!=content){ + QString oldValue = m_content; + m_content=content; + update(); + notify("content",oldValue,m_content); + } +} + +void BarcodeItem::setBarcodeType(BarcodeItem::BarcodeType value) +{ + if (m_barcodeType!=value){ + BarcodeType oldValue = m_barcodeType; + m_barcodeType = value; + update(); + notify("barcodeType",oldValue,value); + } +} + +void BarcodeItem::setDesignTestValue(QString value) +{ + if (m_designTestValue!=value){ + QString oldValue = m_designTestValue; + m_designTestValue=value; + update(); + notify("testValue",oldValue,value); + } +} + +void BarcodeItem::setForegroundColor(QColor value) +{ + if (m_foregroundColor != value){ + QColor oldValue = m_foregroundColor; + m_foregroundColor=value; + update(); + notify("foregroundColor",oldValue,value); + } +} + +void BarcodeItem::setBackgroundColor(QColor value) +{ + if (m_backgroundColor != value){ + QColor oldValue = m_backgroundColor; + m_backgroundColor=value; + update(); + notify("backgroundColor",oldValue,value); + } +} + +void BarcodeItem::setWhitespace(int value) +{ + if (m_whitespace != value){ + int oldValue = m_whitespace; + m_whitespace = value; + update(); + notify("whitespace",oldValue,value); + } +} + +BarcodeItem::AngleType BarcodeItem::angle() const +{ + return m_angle; +} + +void BarcodeItem::setAngle(const AngleType &angle) +{ + if (m_angle!=angle){ + AngleType oldValue = m_angle; + m_angle = angle; + if (!isLoading()){ + update(); + notify("angle",oldValue,angle); + } + } +} + +int BarcodeItem::barcodeWidth() const +{ + return m_barcodeWidth; +} + +void BarcodeItem::setBarcodeWidth(int barcodeWidth) +{ + if (m_barcodeWidth != barcodeWidth){ + int oldValue = m_barcodeWidth; + m_barcodeWidth = barcodeWidth; + if (!isLoading()){ + update(); + notify("barcodeWidth",oldValue,m_barcodeWidth); + } + } +} + +int BarcodeItem::securityLevel() const +{ + return m_securityLevel; +} + +void BarcodeItem::setSecurityLevel(int securityLevel) +{ + if (m_securityLevel != securityLevel){ + int oldValue = m_securityLevel; + m_securityLevel = securityLevel; + if (!isLoading()){ + update(); + notify("securityLevel",oldValue,m_securityLevel); + } + } +} + +int BarcodeItem::pdf417CodeWords() const +{ + return m_pdf417CodeWords; +} + +void BarcodeItem::setPdf417CodeWords(int pdf417CodeWords) +{ + if (m_pdf417CodeWords != pdf417CodeWords){ + int oldValue = m_pdf417CodeWords; + m_pdf417CodeWords = pdf417CodeWords; + if (!isLoading()){ + update(); + notify("pdf417CodeWords",oldValue,m_pdf417CodeWords); + } + } +} + +void BarcodeItem::updateItemSize(RenderPass pass, int) +{ + switch(pass){ + case FirstPass: + setContent(expandUserVariables(content(),pass,NoEscapeSymbols)); + setContent(expandDataFields(content(),NoEscapeSymbols)); + break; + default:; + } +} + +bool BarcodeItem::isNeedUpdateSize(RenderPass pass) const +{return (pass==FirstPass)?true:false;} + +} diff --git a/src/items/lrbarcodeitem.h b/src/items/lrbarcodeitem.h new file mode 100644 index 0000000..001aec0 --- /dev/null +++ b/src/items/lrbarcodeitem.h @@ -0,0 +1,173 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRBARCODEITEM_H +#define LRBARCODEITEM_H +#include "lritemdesignintf.h" +#include + +namespace LimeReport{ + +class BarcodeItem : public LimeReport::ContentItemDesignIntf { + Q_OBJECT + Q_ENUMS(BarcodeType) + Q_ENUMS(AngleType) + Q_PROPERTY(QString content READ content WRITE setContent) + Q_PROPERTY(BarcodeType barcodeType READ barcodeType WRITE setBarcodeType ) + Q_PROPERTY(QString testValue READ designTestValue WRITE setDesignTestValue) + Q_PROPERTY(QColor foregroundColor READ foregroundColor WRITE setForegroundColor) + Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) + Q_PROPERTY(int whitespace READ whitespace WRITE setWhitespace) + Q_PROPERTY(AngleType angle READ angle WRITE setAngle) + Q_PROPERTY(int barcodeWidth READ barcodeWidth WRITE setBarcodeWidth) + Q_PROPERTY(int securityLevel READ securityLevel WRITE setSecurityLevel) + Q_PROPERTY(int pdf417CodeWords READ pdf417CodeWords WRITE setPdf417CodeWords) +public: +// enum BarcodeType {QRCODE=58,CODE128=20,DATAMATRIX=71,MAXICODE=57,MICROPDF417=84}; +// enum BarcodeType {CODE_11=1,C25MATRIX=2,QRCODE=58,CODE128=20,DATAMATRIX=71,MAXICODE=57,MICROPDF417=84, +// EAN=13,PDF417=55, TELEPEN_NUM=87,ITF14=89, KIX=90, MICROQR=97, +// EAN14=72,CHANNEL=140,CODEONE=141,GRIDMATRIX=142}; + enum BarcodeType { + CODE11 =1, + C25MATRIX =2, + C25INTER =3, + C25IATA =4, + C25LOGIC =6, + C25IND =7, + CODE39 =8, + EXCODE39 =9, + EANX =13, + EAN128 =16, + CODABAR =18, + CODE128 =20, + DPLEIT =21, + DPIDENT =22, + CODE16K =23, + CODE93 =25, + FLAT =28, + RSS14 =29, + RSS_LTD =30, + RSS_EXP =31, + TELEPEN =32, + UPCA =34, + UPCE =37, + POSTNET =40, + MSI_PLESSEY =47, + FIM =49, + LOGMARS =50, + PHARMA =51, + PZN =52, + PHARMA_TWO =53, + PDF417 =55, + PDF417TRUNC =56, + MAXICODE =57, + QRCODE =58, + CODE128B =60, + AUSPOST =63, + AUSREPLY =66, + AUSROUTE =67, + AUSREDIRECT =68, + ISBNX =69, + RM4SCC =70, + DATAMATRIX =71, + ITF14 =72, + CODABLOCKF =74, + NVE18 =75, + KOREAPOST =77, + RSS14STACK =79, + RSS14STACK_OMNI =80, + RSS_EXPSTACK =81, + PLANET =82, + MICROPDF417 =84, + ONECODE =85, + PLESSEY =86, + KIX =90, + AZTEC =92, + DAFT =93, + ITALYPOST =94, + DPD =96, + MICROQR =97, + TELEPEN_NUM =128, + CODE32 =129, + EANX_CC =130, + EAN128_CC =131, + RSS14_CC =132, + RSS_LTD_CC =133, + RSS_EXP_CC =134, + UPCA_CC =135, + UPCE_CC =136, + RSS14STACK_CC =137, + RSS14_OMNI_CC =138, + RSS_EXPSTACK_CC =139 + + }; + enum AngleType{Angle0,Angle90,Angle180,Angle270}; + BarcodeItem(QObject *owner, QGraphicsItem *parent); + ~BarcodeItem(); + virtual BaseDesignIntf* createSameTypeItem(QObject *owner, QGraphicsItem *parent); + virtual void paint(QPainter *ppainter, const QStyleOptionGraphicsItem *option, QWidget *widget); + virtual void updateItemSize(RenderPass pass, int); + virtual bool isNeedUpdateSize(RenderPass pass) const; + void setContent(const QString& content); + QString content() const {return m_content;} + void setBarcodeType(BarcodeType value); + BarcodeType barcodeType(){return m_barcodeType;} + void setDesignTestValue(QString value); + QString designTestValue(){return m_designTestValue;} + QColor foregroundColor(){return m_foregroundColor;} + void setForegroundColor(QColor value); + QColor backgroundColor(){return m_backgroundColor;} + void setBackgroundColor(QColor value); + int whitespace(){return m_whitespace;} + void setWhitespace(int value); + AngleType angle() const; + void setAngle(const AngleType &angle); + int barcodeWidth() const; + void setBarcodeWidth(int barcodeWidth); + int securityLevel() const; + void setSecurityLevel(int securityLevel); + int pdf417CodeWords() const; + void setPdf417CodeWords(int pdf417CodeWords); + +private: + Zint::QZint m_bc; + QString m_content; + QString m_designTestValue; + BarcodeType m_barcodeType; + QColor m_foregroundColor; + QColor m_backgroundColor; + int m_whitespace; + AngleType m_angle; + int m_barcodeWidth; + int m_securityLevel; + int m_pdf417CodeWords; +}; + +} +#endif // LRBARCODEITEM_H diff --git a/src/items/lrhorizontallayout.cpp b/src/items/lrhorizontallayout.cpp new file mode 100644 index 0000000..340b10b --- /dev/null +++ b/src/items/lrhorizontallayout.cpp @@ -0,0 +1,432 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrhorizontallayout.h" +#include "lrdesignelementsfactory.h" + +#include +#include +#include +#include + +#include "lrbasedesignintf.h" + +const QString xmlTag = "HLayout"; + +namespace { + +LimeReport::BaseDesignIntf *createHLayout(QObject *owner, LimeReport::BaseDesignIntf *parent) +{ + return new LimeReport::HorizontalLayout(owner, parent); +} +bool registred = LimeReport::DesignElementsFactory::instance().registerCreator( + xmlTag, + LimeReport::ItemAttribs(QObject::tr("HLayout"), LimeReport::bandTAG), + createHLayout + ); +} + + +namespace LimeReport { + +bool lessThen(BaseDesignIntf *c1, BaseDesignIntf* c2){ + return c1->pos().x()pos().x(); +} + + +HorizontalLayout::HorizontalLayout(QObject *owner, QGraphicsItem *parent) + : LayoutDesignIntf(xmlTag, owner, parent),m_isRelocating(false) +{ + setPosibleResizeDirectionFlags(ResizeBottom); + m_layoutMarker = new LayoutMarker(this); + m_layoutMarker->setParentItem(this); + m_layoutMarker->setColor(Qt::red); + m_layoutMarker->setHeight(height()); + m_layoutMarker->setZValue(1); +} + +HorizontalLayout::~HorizontalLayout() +{ + if (m_layoutMarker) { + delete m_layoutMarker; m_layoutMarker=0; + } +} + +BaseDesignIntf *HorizontalLayout::createSameTypeItem(QObject *owner, QGraphicsItem *parent) +{ + return new LimeReport::HorizontalLayout(owner, parent); +} + +void HorizontalLayout::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + Q_UNUSED(event) +// if ((itemMode() & LayoutEditMode) || isSelected()){ +// setChildVisibility(false); +// } +} + +void HorizontalLayout::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + Q_UNUSED(event) +// setChildVisibility(true); +} + +void HorizontalLayout::geometryChangedEvent(QRectF newRect, QRectF ) +{ + m_layoutMarker->setHeight(newRect.height()); + relocateChildren(); +} + +void HorizontalLayout::setChildVisibility(bool value){ + foreach(QGraphicsItem* child,childItems()){ + BaseDesignIntf* item = dynamic_cast(child); + if(item) + item->setVisible(value); + } +} + +int HorizontalLayout::childrenCount() +{ + return m_children.size(); +} + +void HorizontalLayout::initMode(BaseDesignIntf::ItemMode mode) +{ + BaseDesignIntf::initMode(mode); + if ((mode==PreviewMode)||(mode==PrintMode)){ + m_layoutMarker->setVisible(false); + } else { + m_layoutMarker->setVisible(true); + } +} + +bool HorizontalLayout::canBeSplitted(int height) const +{ + foreach(QGraphicsItem* qgItem,childItems()){ + BaseDesignIntf* item=dynamic_cast(qgItem); + if (item) + if (!item->canBeSplitted(height-item->pos().y())) return false; + } + return true; +} + +BaseDesignIntf *HorizontalLayout::cloneUpperPart(int height, QObject *owner, QGraphicsItem *parent) +{ + HorizontalLayout* upperPart = dynamic_cast(createSameTypeItem(owner,parent)); + upperPart->initFromItem(this); + qreal maxHeight = 0; + foreach(BaseDesignIntf* item,childBaseItems()){ + + if ((item->geometry().top()geometry().bottom()>height)){ + int sliceHeight = height-item->geometry().top(); + if (item->canBeSplitted(sliceHeight)){ + BaseDesignIntf* slicedPart = item->cloneUpperPart(sliceHeight,upperPart,upperPart); + if (maxHeightheight()) maxHeight = slicedPart->height(); + } else { + item->cloneEmpty(sliceHeight,upperPart,upperPart); + item->setPos(item->pos().x(),item->pos().y()+((height+1)-item->geometry().top())); + } + } + } + + foreach(BaseDesignIntf* item, upperPart->childBaseItems()){ + item->setHeight((maxHeightsetHeight(height); + + return upperPart; +} + +BaseDesignIntf *HorizontalLayout::cloneBottomPart(int height, QObject *owner, QGraphicsItem *parent) +{ + qreal maxHeight = 0; + HorizontalLayout* bottomPart = dynamic_cast(createSameTypeItem(owner,parent)); + bottomPart->initFromItem(this); + foreach(BaseDesignIntf* item,childBaseItems()){ + if ((item->geometry().top()geometry().bottom()>height)){ + BaseDesignIntf* tmpItem=item->cloneBottomPart(height,bottomPart,bottomPart); + tmpItem->setPos(tmpItem->pos().x(),0); + if (maxHeightheight()) + maxHeight = tmpItem->height(); + } + } + + if (!bottomPart->isEmpty()){ + foreach (BaseDesignIntf* item, bottomPart->childBaseItems()) { + item->setHeight(maxHeight); + } + bottomPart->setHeight(maxHeight); + } + return bottomPart; +} + +void HorizontalLayout::restoreChild(BaseDesignIntf* item){ + if (m_children.contains(item)) return; + + m_isRelocating=true; + foreach (BaseDesignIntf* child, childBaseItems()) { + if (child->pos()==item->pos()){ + int index = m_children.indexOf(child)-1; + m_children.insert(index,item); + child->setPos(item->pos().x()+item->width(),0); + break; + } + } + + connect(item,SIGNAL(destroyed(QObject*)),this,SLOT(slotOnChildDestroy(QObject*))); + connect(item,SIGNAL(geometryChanged(QObject*,QRectF,QRectF)),this,SLOT(slotOnChildGeometryChanged(QObject*,QRectF,QRectF))); + item->setFixedPos(true); + item->setPosibleResizeDirectionFlags(ResizeRight | ResizeBottom); + item->setParent(this); + item->setParentItem(this); + + updateLayoutSize(); + m_isRelocating=false; +} + +bool HorizontalLayout::isEmpty() const +{ + bool isEmpty = true; + bool allItemsIsText = true; + foreach (QGraphicsItem* qgItem, childItems()) { + ContentItemDesignIntf* item = dynamic_cast(qgItem); + if (item && !item->content().isEmpty()) isEmpty = false; + if (!item && dynamic_cast(qgItem)) + allItemsIsText = false; + } + return (isEmpty && allItemsIsText); +} + +void HorizontalLayout::addChild(BaseDesignIntf *item, bool updateSize) +{ + if (m_children.count() > 0) + item->setPos(m_children.last()->pos().x() + m_children.last()->width(), 0); + else + item->setPos(0, 0); + + m_children.append(item); + item->setParentItem(this); + item->setParent(this); + item->setFixedPos(true); + item->setPosibleResizeDirectionFlags(ResizeRight | ResizeBottom); + + connect(item,SIGNAL(destroyed(QObject*)),this,SLOT(slotOnChildDestroy(QObject*))); + connect(item,SIGNAL(geometryChanged(QObject*,QRectF,QRectF)),this,SLOT(slotOnChildGeometryChanged(QObject*,QRectF,QRectF))); + + if (updateSize){ + relocateChildren(); + updateLayoutSize(); + } +} + +void HorizontalLayout::collectionLoadFinished(const QString &collectionName) +{ + ItemDesignIntf::collectionLoadFinished(collectionName); + if (collectionName.compare("children",Qt::CaseInsensitive)==0){ +#ifdef HAVE_QT5 + foreach(QObject* obj,children()){ +#else + foreach(QObject* obj,QObject::children()){ +#endif + BaseDesignIntf* item = dynamic_cast(obj); + if (item) { + addChild(item,false); + } + } + } +} + +void HorizontalLayout::objectLoadFinished() +{ + m_layoutMarker->setHeight(height()); + LayoutDesignIntf::objectLoadFinished(); +} + +void HorizontalLayout::updateLayoutSize() +{ + int w = 0; + qreal h = 0; + foreach(BaseDesignIntf* item, m_children){ + if (hheight()) h=item->height(); + w+=item->width(); + } + if (h>0) setHeight(h); + setWidth(w); +} + +void HorizontalLayout::relocateChildren() +{ + if (m_children.count()setPos(curX,0); + curX+=item->width(); + item->setHeight(height()); + } + m_isRelocating = false; +} + +void HorizontalLayout::beforeDelete() +{ + m_children.clear(); +#ifdef HAVE_QT5 + foreach (QObject *item, children()) { +#else + foreach (QObject *item, QObject::children()) { +#endif + BaseDesignIntf *bdItem = dynamic_cast(item); + if (bdItem) { + bdItem->setParentItem(parentItem()); + bdItem->setParent(parent()); + bdItem->setVisible(true); + bdItem->setPos(mapToParent(bdItem->pos())); + bdItem->setFixedPos(false); + bdItem->setPosibleResizeDirectionFlags(AllDirections); + } + } +} + +void HorizontalLayout::updateItemSize(RenderPass pass, int maxHeight) +{ + m_isRelocating=true; + ItemDesignIntf::updateItemSize(pass,maxHeight); + foreach(QGraphicsItem *child, childItems()){ + BaseDesignIntf* item = dynamic_cast(child); + if (item) item->updateItemSize(pass,maxHeight); + } + updateLayoutSize(); + relocateChildren(); + m_isRelocating=false; +} + +bool HorizontalLayout::isNeedUpdateSize(RenderPass pass) const +{ + foreach (QGraphicsItem *child, childItems()) { + BaseDesignIntf* item = dynamic_cast(child); + if (item && item->isNeedUpdateSize(pass)) + return true; + } + return false; +} + +void HorizontalLayout::childAddedEvent(BaseDesignIntf *child) +{ + addChild(child,false); +} + +void HorizontalLayout::slotOnChildDestroy(QObject* child) +{ + m_children.removeAll(static_cast(child)); + if (m_children.count()<2){ + beforeDelete(); +// deleteLater(); + } else { + relocateChildren(); + updateLayoutSize(); + } +} + +void HorizontalLayout::slotOnChildGeometryChanged(QObject *, QRectF newGeometry, QRectF) +{ + if (!m_isRelocating){ + setHeight(newGeometry.height()); + relocateChildren(); + updateLayoutSize(); + } +} + +LayoutMarker::LayoutMarker(HorizontalLayout *layout, QGraphicsItem *parent) + :QGraphicsItem(parent), m_rect(0,0,30,30), m_color(Qt::red), m_layout(layout){ + setFlag(QGraphicsItem::ItemIsMovable); +} + +void LayoutMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) +{ + painter->save(); + painter->setOpacity(LAYOUT_MARKER_OPACITY); + painter->fillRect(boundingRect(),m_color); + + painter->setRenderHint(QPainter::Antialiasing); + qreal size = (boundingRect().width()isSelected()){ + painter->setOpacity(1); + QRectF r = QRectF(0,0,size,size); + painter->setBrush(Qt::white); + painter->setPen(Qt::white); + painter->drawEllipse(r.adjusted(5,5,-5,-5)); + painter->setBrush(m_color); + painter->drawEllipse(r.adjusted(7,7,-7,-7)); + } + painter->restore(); +} + +void LayoutMarker::setHeight(qreal height) +{ + if (m_rect.height()!=height){ + prepareGeometryChange(); + m_rect.setHeight(height); + } +} + +void LayoutMarker::setWidth(qreal width) +{ + if (m_rect.width()!=width){ + prepareGeometryChange(); + m_rect.setWidth(width); + } +} + +void LayoutMarker::setColor(QColor color) +{ + if (m_color!=color){ + m_color = color; + update(boundingRect()); + } +} + +void LayoutMarker::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (event->button()==Qt::LeftButton) { + if (!(event->modifiers() & Qt::ControlModifier)) + m_layout->scene()->clearSelection(); + m_layout->setSelected(true); + //m_layout->setChildVisibility(false); + update(0,0,boundingRect().width(),boundingRect().width()); + } +} + +} // namespace LimeReport diff --git a/src/items/lrhorizontallayout.h b/src/items/lrhorizontallayout.h new file mode 100644 index 0000000..5e480be --- /dev/null +++ b/src/items/lrhorizontallayout.h @@ -0,0 +1,101 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRHORIZONTALLAYOUT_H +#define LRHORIZONTALLAYOUT_H +#include "lritemdesignintf.h" + +namespace LimeReport +{ + +class HorizontalLayout; + +class LayoutMarker : public QGraphicsItem{ +public: + explicit LayoutMarker(HorizontalLayout* layout, QGraphicsItem *parent=0); + virtual QRectF boundingRect() const{return m_rect;} + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *); + void setHeight(qreal height); + void setWidth(qreal width); + void setColor(QColor color); + qreal width(){return m_rect.width();} + qreal height(){return m_rect.height();} +protected: + void mousePressEvent(QGraphicsSceneMouseEvent *event); +private: + QRectF m_rect; + QColor m_color; + HorizontalLayout* m_layout; +}; + +class HorizontalLayout : public LayoutDesignIntf +{ + Q_OBJECT +public: + HorizontalLayout(QObject *owner = 0, QGraphicsItem *parent = 0); + ~HorizontalLayout(); + BaseDesignIntf *createSameTypeItem(QObject *owner = 0, QGraphicsItem *parent = 0); + void hoverEnterEvent(QGraphicsSceneHoverEvent *event); + void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); + void geometryChangedEvent(QRectF newRect, QRectF); + void addChild(BaseDesignIntf *item,bool updateSize=true); + friend class BaseDesignIntf; + void restoreChild(BaseDesignIntf *item); + bool isEmpty() const; +protected: + void collectionLoadFinished(const QString &collectionName); + void objectLoadFinished(); + void updateLayoutSize(); + void relocateChildren(); + void beforeDelete(); + void updateItemSize(RenderPass pass, int maxHeight); + bool isNeedUpdateSize(RenderPass pass) const; + void childAddedEvent(BaseDesignIntf *child); + void setChildVisibility(bool value); + int childrenCount(); + void initMode(ItemMode mode); + + bool canBeSplitted(int height) const; + BaseDesignIntf* cloneUpperPart(int height, QObject* owner=0, QGraphicsItem* parent=0); + BaseDesignIntf* cloneBottomPart(int height, QObject *owner=0, QGraphicsItem *parent=0); + +private slots: + void slotOnChildDestroy(QObject *child); + void slotOnChildGeometryChanged(QObject*, QRectF newGeometry, QRectF); + //void slotOnPosChanged(QObject*, QPointF newPos, QPointF ); +private: + QList m_children; + bool m_isRelocating; + LayoutMarker* m_layoutMarker; + + friend class LayoutMarker; +}; + +} //namespace LimeReport +#endif // LRHORIZONTALLAYOUT_H diff --git a/src/items/lrimageitem.cpp b/src/items/lrimageitem.cpp new file mode 100644 index 0000000..c573167 --- /dev/null +++ b/src/items/lrimageitem.cpp @@ -0,0 +1,261 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrimageitem.h" +#include "lrdesignelementsfactory.h" +#include "lrglobal.h" +#include "lrdatasourcemanager.h" + +namespace{ + +const QString xmlTag = "ImageItem"; + +LimeReport::BaseDesignIntf * createImageItem(QObject* owner, LimeReport::BaseDesignIntf* parent){ + return new LimeReport::ImageItem(owner,parent); +} +bool registred = LimeReport::DesignElementsFactory::instance().registerCreator( + xmlTag, LimeReport::ItemAttribs(QObject::tr("Image Item"),"Item"), createImageItem + ); +} + +namespace LimeReport{ + +ImageItem::ImageItem(QObject* owner,QGraphicsItem* parent) + :ItemDesignIntf(xmlTag,owner,parent),m_autoSize(false), m_scale(true), m_keepAspectRatio(true), m_center(true){} + +BaseDesignIntf *ImageItem::createSameTypeItem(QObject *owner, QGraphicsItem *parent) +{ + return new ImageItem(owner,parent); +} + +void ImageItem::updateItemSize(RenderPass , int ) +{ + if (!m_datasource.isEmpty() && !m_field.isEmpty() && m_picture.isNull()){ + DataSourceManager* dm = DataSourceManager::instance(); + IDataSource* ds = dm->dataSource(m_datasource); + if (ds) { + QVariant data = ds->data(m_field); + if (data.isValid()){ + if (data.type()==QVariant::Image){ + m_picture = data.value(); + } else + m_picture.loadFromData(data.toByteArray()); + } + } + } + if (m_autoSize){ + setWidth(m_picture.width()); + setHeight(m_picture.height()); + } +} + +bool ImageItem::isNeedUpdateSize(RenderPass) const +{ + return m_picture.isNull() || m_autoSize; +} + +qreal ImageItem::minHeight() const{ + if (!m_picture.isNull() && autoSize()) + { + return m_picture.height(); + } else { + return 0; + } +} + +bool ImageItem::center() const +{ + return m_center; +} + +void ImageItem::setCenter(bool center) +{ + if (m_center != center){ + m_center = center; + update(); + notify("center",!center,center); + } +} + +bool ImageItem::keepAspectRatio() const +{ + return m_keepAspectRatio; +} + +void ImageItem::setKeepAspectRatio(bool keepAspectRatio) +{ + if (m_keepAspectRatio != keepAspectRatio){ + m_keepAspectRatio = keepAspectRatio; + update(); + notify("keepAspectRatio",!keepAspectRatio,keepAspectRatio); + } +} + +bool ImageItem::scale() const +{ + return m_scale; +} + +void ImageItem::setScale(bool scale) +{ + if (m_scale != scale){ + m_scale = scale; + update(); + notify("scale",!scale,scale); + } +} +bool ImageItem::autoSize() const +{ + return m_autoSize; +} + +void ImageItem::setAutoSize(bool autoSize) +{ + if (m_autoSize != autoSize){ + m_autoSize = autoSize; + if (m_autoSize && !m_picture.isNull()){ + setWidth(image().width()); + setHeight(image().height()); + setPosibleResizeDirectionFlags(Fixed); + } else { + setPosibleResizeDirectionFlags(AllDirections); + } + update(); + notify("autoSize",!autoSize,autoSize); + } +} + +QString ImageItem::field() const +{ + return m_field; +} + +void ImageItem::setField(const QString &field) +{ + if (m_field != field){ + QString oldValue = m_field; + m_field = field; + update(); + notify("field",oldValue,field); + } +} + +QString ImageItem::datasource() const +{ + return m_datasource; +} + +void ImageItem::setDatasource(const QString &datasource) +{ + if (m_datasource != datasource){ + QString oldValue = m_datasource; + m_datasource = datasource; + update(); + notify("datasource",oldValue,datasource); + } +} + + +void ImageItem::paint(QPainter *ppainter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + ppainter->save(); + if (isSelected()) ppainter->setOpacity(SELECTION_OPACITY); + else ppainter->setOpacity(qreal(opacity())/100); + + QPointF point = rect().topLeft(); + QImage img; + + if (m_scale && !image().isNull()){ + img = image().scaled(rect().width(), rect().height(), keepAspectRatio() ? Qt::KeepAspectRatio : Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + } else { + img = image(); + } + + qreal shiftHeight = rect().height() - img.height(); + qreal shiftWidth = rect().width() - img.width(); + + if (m_center){ + if (shiftHeight<0 || shiftWidth<0){ + qreal cutX = 0; + qreal cutY = 0; + qreal cutWidth = img.width(); + qreal cutHeigth = img.height(); + + if (shiftWidth > 0){ + point.setX(point.x()+shiftWidth/2); + } else { + cutX = abs(shiftWidth/2); + cutWidth += shiftWidth; + } + + if (shiftHeight > 0){ + point.setY(point.x()+shiftHeight/2); + } else { + cutY = abs(shiftHeight/2); + cutHeigth += shiftHeight; + } + + img = img.copy(cutX,cutY,cutWidth,cutHeigth); + } else { + point.setX(point.x()+shiftWidth/2); + point.setY(point.y()+shiftHeight/2); + } + } + + if (img.isNull() && itemMode()==DesignMode){ + QString text; + ppainter->setFont(transformToSceneFont(QFont("Arial",10))); + if (!datasource().isEmpty() && !field().isEmpty()) + text = datasource()+"."+field(); + else text = tr("Image"); + ppainter->drawText(rect().adjusted(4,4,-4,-4), Qt::AlignCenter, text ); + } else { + ppainter->drawImage(point,img); + } + ItemDesignIntf::paint(ppainter,option,widget); + ppainter->restore(); +} + +void ImageItem::setImage(QImage value) +{ + if (m_picture!=value){ + QImage oldValue = m_picture; + m_picture=value; + if (m_autoSize){ + setWidth(m_picture.width()); + setHeight(m_picture.height()); + } + update(); + notify("image",oldValue,value); + } +} + + + +} diff --git a/src/items/lrimageitem.h b/src/items/lrimageitem.h new file mode 100644 index 0000000..7a0f734 --- /dev/null +++ b/src/items/lrimageitem.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRIMAGEITEM_H +#define LRIMAGEITEM_H +#include "lritemdesignintf.h" + +namespace LimeReport{ + +class ImageItem : public LimeReport::ItemDesignIntf +{ + Q_OBJECT + Q_PROPERTY(QImage image READ image WRITE setImage) + Q_PROPERTY(int opacity READ opacity WRITE setOpacity) + Q_PROPERTY(QString datasource READ datasource WRITE setDatasource) + Q_PROPERTY(QString field READ field WRITE setField) + Q_PROPERTY(bool autoSize READ autoSize WRITE setAutoSize) + Q_PROPERTY(bool scale READ scale WRITE setScale) + Q_PROPERTY(bool keepAspectRatio READ keepAspectRatio WRITE setKeepAspectRatio) + Q_PROPERTY(bool center READ center WRITE setCenter) +public: + ImageItem(QObject *owner, QGraphicsItem *parent); + virtual void paint(QPainter *ppainter, const QStyleOptionGraphicsItem *option, QWidget *widget); + void setImage(QImage value); + QImage image(){return m_picture;} + void setContent(const QString &value){m_content=value;} + QString datasource() const; + void setDatasource(const QString &datasource); + QString field() const; + void setField(const QString &field); + + bool autoSize() const; + void setAutoSize(bool autoSize); + bool scale() const; + void setScale(bool scale); + bool keepAspectRatio() const; + void setKeepAspectRatio(bool keepAspectRatio); + bool center() const; + void setCenter(bool center); + + qreal minHeight() const; + +protected: + BaseDesignIntf* createSameTypeItem(QObject *owner, QGraphicsItem *parent); + void updateItemSize(RenderPass, int); + bool isNeedUpdateSize(RenderPass) const; +private: + QImage m_picture; + QString m_content; + QString m_datasource; + QString m_field; + bool m_autoSize; + bool m_scale; + bool m_keepAspectRatio; + bool m_center; +}; + +} +#endif // LRIMAGEITEM_H diff --git a/src/items/lrshapeitem.cpp b/src/items/lrshapeitem.cpp new file mode 100644 index 0000000..390ded6 --- /dev/null +++ b/src/items/lrshapeitem.cpp @@ -0,0 +1,190 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrshapeitem.h" +#include "lrdesignelementsfactory.h" +#include +#include + +namespace{ + +const QString xmlTag = "ShapeItem"; + +LimeReport::BaseDesignIntf * createShapeItem(QObject* owner, LimeReport::BaseDesignIntf* parent){ + return new LimeReport::ShapeItem(owner,parent); +} +bool registred = LimeReport::DesignElementsFactory::instance().registerCreator( + xmlTag, LimeReport::ItemAttribs(QObject::tr("Shape Item"),"Item"), createShapeItem + ); +} + + +namespace LimeReport{ + +ShapeItem::ShapeItem(QObject *owner, QGraphicsItem *parent) + :ItemDesignIntf(xmlTag,owner,parent), + m_shape(HorizontalLine), + m_shapeColor(Qt::black), + m_shapeBrushColor(Qt::black), + m_shapeBrushType(Qt::NoBrush), + m_lineWidth(1), + m_penStyle(Qt::SolidLine), + m_opacity(100) +{ +} + +void ShapeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + painter->save(); + + QPen pen(m_shapeColor); + pen.setWidthF(m_lineWidth); + pen.setStyle(m_penStyle); + painter->setPen(pen); + QBrush brush(m_shapeBrushColor,m_shapeBrushType); + + painter->setBrush(brush); + painter->setBackground(QBrush(Qt::NoBrush)); + painter->setOpacity(qreal(m_opacity)/100); + + switch (m_shape){ + case HorizontalLine: + painter->drawLine(0,rect().height()/2,rect().right(),rect().height()/2); + break; + case VerticalLine: + painter->drawLine(rect().width()/2,0,rect().width()/2,rect().height()); + break; + case Ellipse: + painter->setRenderHint(QPainter::Antialiasing); + painter->drawEllipse(rect()); + break; + case Rectangle: + painter->setRenderHint(QPainter::Antialiasing); + painter->drawRect(rect()); + break; + } + painter->restore(); + ItemDesignIntf::paint(painter,option,widget); + +} + +void ShapeItem::setShapeColor(QColor value) +{ + if ((value!=m_shapeColor)){ + QColor oldValue = m_shapeColor; + m_shapeColor=value; + update(); + notify("shapeColor",oldValue,value); + } +} + +void ShapeItem::setShapeBrushColor(QColor value) +{ + if (value!=m_shapeBrushColor){ + QColor oldValue = m_shapeBrushColor; + m_shapeBrushColor=value; + update(); + notify("shapeBrushColor",oldValue,value); + } +} + +void ShapeItem::setShapeBrushType(Qt::BrushStyle value) +{ + if (m_shapeBrushType!=value){ + Qt::BrushStyle oldValue = m_shapeBrushType; + m_shapeBrushType=value; + update(rect()); + notify("shapeBrush",QBrush(oldValue),QBrush(value)); + } +} + +void ShapeItem::setShapeType(ShapeItem::ShapeType value) +{ + if (m_shape!=value){ + ShapeType oldValue = m_shape; + m_shape=value; + update(); + notify("shape",oldValue,value); + } +} + +void ShapeItem::setLineWidth(qreal value) +{ + if (m_lineWidth!=value){ + qreal oldValue = m_lineWidth; + m_lineWidth=value; + update(); + notify("lineWidth",oldValue,value); + + } +} + +Qt::PenStyle ShapeItem::penStyle() const +{ + return m_penStyle; +} + +void ShapeItem::setPenStyle(const Qt::PenStyle &value) +{ + if (m_penStyle!=value){ + Qt::PenStyle oldValue = m_penStyle; + m_penStyle = value; + update(); + notify("penStyle",(int)oldValue,(int)value); + } +} + +BaseDesignIntf *ShapeItem::createSameTypeItem(QObject *owner, QGraphicsItem *parent) +{ + return new ShapeItem(owner,parent); +} +int ShapeItem::opacity() const +{ + return m_opacity; +} + +void ShapeItem::setOpacity(int opacity) +{ + if (m_opacity!=opacity){ + if (opacity < 0) { + m_opacity = 0; + } + else if (opacity > 100) { + m_opacity = 100; + } + else { + m_opacity = opacity; + } + update(); + } +} + + + +} diff --git a/src/items/lrshapeitem.h b/src/items/lrshapeitem.h new file mode 100644 index 0000000..84cc6d9 --- /dev/null +++ b/src/items/lrshapeitem.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRSHAPEITEM_H +#define LRSHAPEITEM_H +#include "lritemdesignintf.h" + +namespace LimeReport{ + +class ShapeItem: public LimeReport::ItemDesignIntf +{ + Q_OBJECT + Q_ENUMS(ShapeType) + Q_PROPERTY(ShapeType shape READ shapeType WRITE setShapeType) + Q_PROPERTY(QColor shapeColor READ shapeColor WRITE setShapeColor) + Q_PROPERTY(QColor shapeBrushColor READ shapeBrushColor WRITE setShapeBrushColor) + Q_PROPERTY(Qt::BrushStyle shapeBrush READ shapeBrushType WRITE setShapeBrushType) + Q_PROPERTY(qreal lineWidth READ lineWidth WRITE setLineWidth) + Q_PROPERTY(Qt::PenStyle penStyle READ penStyle WRITE setPenStyle) + Q_PROPERTY(int opacity READ opacity WRITE setOpacity) +public: + enum ShapeType{HorizontalLine,VerticalLine,Ellipse,Rectangle}; + ShapeItem(QObject *owner, QGraphicsItem *parent); + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + void setShapeColor(QColor value); + QColor shapeColor() const {return m_shapeColor;} + void setShapeBrushColor(QColor value); + QColor shapeBrushColor() const {return m_shapeBrushColor;} + void setShapeBrushType(Qt::BrushStyle value); + Qt::BrushStyle shapeBrushType() const {return m_shapeBrushType;} + void setShapeType(ShapeType value); + ShapeType shapeType() const {return m_shape;} + void setLineWidth(qreal value); + qreal lineWidth() const {return m_lineWidth;} + Qt::PenStyle penStyle() const; + void setPenStyle(const Qt::PenStyle &value); + int opacity() const; + void setOpacity(int opacity); + +protected: + virtual BaseDesignIntf* createSameTypeItem(QObject *owner, QGraphicsItem *parent); +private: + ShapeType m_shape; + QColor m_shapeColor; + QColor m_shapeBrushColor; + Qt::BrushStyle m_shapeBrushType; + qreal m_lineWidth; + Qt::PenStyle m_penStyle; + int m_opacity; +}; + +} +#endif // LRSHAPEITEM_H diff --git a/src/items/lrsimpletagparser.cpp b/src/items/lrsimpletagparser.cpp new file mode 100644 index 0000000..128cb8c --- /dev/null +++ b/src/items/lrsimpletagparser.cpp @@ -0,0 +1,238 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrsimpletagparser.h" +#include +#include +#include + +namespace LimeReport{ +void HtmlContext::fillTagVector(QString html) +{ + QRegExp rx("<[^<]*>"); + QString buff=html; + int curPos=0; + while(buff.contains(rx)){ + int pos=rx.indexIn(buff); + curPos+=pos; + buff=buff.right(buff.length()-pos); + if (rx.cap().at(1)!='/'){ + int initPos=curPos; + parseTag(m_tags,buff,initPos); + } + buff=buff.right(buff.length()-rx.matchedLength()); + } +} + +QString HtmlContext::parseTag(QVector &storage, QString text, int &curPos, bool createTag) +{ + QRegExp rx("<[^<]*>"); + int pos=rx.indexIn(text); + int begPos=pos+curPos; + QString buff=text.right(text.length()-(pos+rx.matchedLength())); + + QString tagName=rx.cap(0); + tagName.remove('<'); + tagName.remove('>'); + + while (buff.contains(rx)){ + int pos=rx.indexIn(buff); + buff=buff.right(buff.length()-pos); + curPos+=pos; + if (extractWord(rx.cap(0),1).compare(extractWord(tagName,1),Qt::CaseInsensitive)==0){ + if (rx.cap(0).at(1)=='/'){ + if (createTag) storage.append(new Tag(tagName,begPos,curPos)); + return buff.right(buff.length()-rx.matchedLength()); + } else { + buff=parseTag(storage,buff,curPos,false); + + } + } else { + buff=buff.right(buff.length()-rx.matchedLength()); + } + } + return ""; +} + +void HtmlContext::parseSymbs(QString text) +{ + + QRegExp rx("<[^<]*[^/]>"); + while (text.contains(rx)){ + int pos=rx.indexIn(text); + if (rx.cap().compare("
",Qt::CaseInsensitive)==0) + m_symbs.append(new Symb(rx.cap(),pos)); + text.remove(pos,rx.matchedLength()); + } + + foreach(QString pattern,m_symbPatterns){ + rx.setPattern(pattern); + while (text.contains(rx)){ + int pos=rx.indexIn(text); + m_symbs.append(new Symb(rx.cap(0),pos)); + text.replace(rx.cap(0)," "); + } + } +} + +void HtmlContext::initSymbPatterns() +{ + m_symbPatterns<<"&[^&]*;"<<"<[^<]*/>"; +} + +HtmlContext::HtmlContext(QString html) +{ + fillTagVector(html); + parseSymbs(html); + initSymbPatterns(); +} + +HtmlContext::~HtmlContext() +{ + clearTags(); + clearSymbs(); +} + +QString HtmlContext::extractWord(QString text, int index) +{ + text.remove('<'); + text.remove('>'); + text.remove('/'); + int counter=1; + QString retWord(""); + for (int i=0;i HtmlContext::tagVectDiff(QVector source, QVector dest) +{ + QVector resVect; + for(int i=0;i source, QVector dest) +{ + if (source.count()!=dest.count()) return false; + foreach(Tag* tag,source){ + if (!dest.contains(tag)) return false; + } + return true; +} + +QString HtmlContext::extendTextByTags(QString text, int pos) +{ + QString curText=""; + QVector curTags=tagsAt(pos); + for(int i=0;itagText()+'>'; + } + + for(int i=0;i tagsAtPos=tagsAt(pos); + if (!HtmlContext::isVectorEqual(curTags,tagsAtPos)){ + QVector diffs=HtmlContext::tagVectDiff(curTags,tagsAtPos); + foreach(TagDiff diff,diffs){ + if (diff.direction==TagDiff::Inner){ + curText+='<'+diff.tag->tagText()+'>'; + curTags.append(diff.tag); + } + else{ + curText+="tagText(),1)+'>'; + curTags.remove(curTags.indexOf(diff.tag)); + } + } + } + Symb s=symbAt(pos); + if (s.isValid()){ + if (s.isTag()) curText+=s.text()+text.at(i); + else curText+=s.text(); + } else curText+=text.at(i); + } + + curTags=tagsAt(pos); + for(int i=0;itagText(),1)+'>'; + } + + return curText; +} + +QVector HtmlContext::tagsAt(int pos) +{ + QVector result; + foreach(Tag* tag,m_tags){ + if ((pos>=tag->begin())&&(pos<=tag->end())) result.append(tag); + } + return result; +} + +Symb HtmlContext::symbAt(int pos) +{ + foreach(Symb* symb,m_symbs){ + if (pos==symb->pos()) return *symb; + } + return Symb(); +} + +void HtmlContext::clearTags() +{ + foreach(Tag* tag,m_tags) delete tag; + m_tags.clear(); +} + +void HtmlContext::clearSymbs() +{ + foreach(Symb* symb,m_symbs) delete symb; + m_tags.clear(); +} + +} diff --git a/src/items/lrsimpletagparser.h b/src/items/lrsimpletagparser.h new file mode 100644 index 0000000..6463edc --- /dev/null +++ b/src/items/lrsimpletagparser.h @@ -0,0 +1,100 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRSIMPLETAGPARSER_H +#define LRSIMPLETAGPARSER_H + +#include +#include +#include + +namespace LimeReport{ + +class Tag{ +public: + Tag(QString text,int beginPos,int endPos) + :m_tagText(text),m_beginPos(beginPos),m_endPos(endPos){} + Tag():m_tagText(""),m_beginPos(-1),m_endPos(-1){} + bool isValid(){return (!m_tagText.isEmpty())&&(m_beginPos>0)&&(m_endPos>0);} + QString tagText() const {return m_tagText;} + int begin() const {return m_beginPos;} + int end() const {return m_endPos;} +private: + QString m_tagText; + int m_beginPos; + int m_endPos; +}; + +class Symb{ +public: + Symb(QString text, int pos):m_text(text),m_pos(pos){} + Symb():m_text(""),m_pos(-1){} + bool isValid(){return (!m_text.isEmpty())&&(m_pos>0);} + bool isTag(){return isValid()&&m_text.at(0)=='<';} + QString text(){return m_text;} + int pos(){return m_pos;} +private: + QString m_text; + int m_pos; +}; + +struct TagDiff{ + enum Direction { + Inner=0, + Outer=1 + }; + Tag* tag; + Direction direction; +}; + +class HtmlContext +{ +public: + HtmlContext(QString html); + ~HtmlContext(); + static QString extractWord(QString text,int index); + static QVector tagVectDiff(QVector source, QVector dest); + static bool isVectorEqual(QVector source, QVector dest); + void fillTagVector(QString html); + QString extendTextByTags(QString text, int pos); + QVector tagsAt(int pos); + Symb symbAt(int pos); + void clearTags(); + void clearSymbs(); +private: + static QString parseTag(QVector& storage,QString text,int& curPos, bool createTag=true); + void parseSymbs(QString text); + void initSymbPatterns(); +private: + QVector m_tags; + QVector m_symbs; + QStringList m_symbPatterns; +}; +} +#endif // LRSIMPLETAGPARSER_H diff --git a/src/items/lrsubitemparentpropitem.cpp b/src/items/lrsubitemparentpropitem.cpp new file mode 100644 index 0000000..3380660 --- /dev/null +++ b/src/items/lrsubitemparentpropitem.cpp @@ -0,0 +1,97 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrsubitemparentpropitem.h" +#include "../objectinspector/editors/lrcomboboxeditor.h" +#include "lrbasedesignintf.h" +#include "lritemdesignintf.h" +#include "lrpagedesignintf.h" +#include "lrobjectpropitem.h" + + +namespace{ + LimeReport::ObjectPropItem * createLocationPropItem( + QObject *object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly) + { + return new LimeReport::ItemLocationPropItem(object, objects, name, displayName, data, parent, readonly); + } + bool registred = LimeReport::ObjectPropFactory::instance().registerCreator( + LimeReport::APropIdent("itemLocation","LimeReport::ItemDesignIntf"),QObject::tr("itemLocation"),createLocationPropItem + ); +} + +LimeReport::ItemLocationPropItem::ItemLocationPropItem(QObject* object, ObjectsList* objects, const QString &name, const QString &displayName, const QVariant &value, ObjectPropItem* parent, bool readonly) + :LimeReport::ObjectPropItem(object, objects, name, displayName, value, parent, readonly){ + m_locationMap.insert("Band",LimeReport::ItemDesignIntf::Band); + m_locationMap.insert("Page",LimeReport::ItemDesignIntf::Page); +} + + +QWidget * LimeReport::ItemLocationPropItem::createProperyEditor(QWidget *parent) const{ + ComboBoxEditor *editor = new ComboBoxEditor(parent); + connect(editor,SIGNAL(currentIndexChanged(QString)),this,SLOT(slotLocationChanged(QString))); + LimeReport::BaseDesignIntf *item=dynamic_cast(object()); + if (item){ + QStringList locationTypes; + foreach(QString location,m_locationMap.keys()){ + locationTypes.append(location); + } + editor->addItems(locationTypes); + } + return editor; +} + +QString LimeReport::ItemLocationPropItem::displayValue() const{ + return locationToString(static_cast(propertyValue().toInt())); +} + +void LimeReport::ItemLocationPropItem::setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const{ + ComboBoxEditor *editor=qobject_cast(propertyEditor); + editor->setTextValue(locationToString(propertyValue().toInt())); +} + +void LimeReport::ItemLocationPropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index){ + object()->setProperty(propertyName().toLatin1(),stringToLocation(qobject_cast(propertyEditor)->text())); + model->setData(index,object()->property(propertyName().toLatin1())); +} + +QString LimeReport::ItemLocationPropItem::locationToString(LimeReport::ItemDesignIntf::LocationType location) const{ + return m_locationMap.key(location); +} + +LimeReport::ItemDesignIntf::LocationType LimeReport::ItemLocationPropItem::stringToLocation(const QString &locationName){ + return m_locationMap.value(locationName); +} + +void LimeReport::ItemLocationPropItem::slotLocationChanged(const QString &text){ + if ( locationToString(object()->property(propertyName().toLatin1()).toInt())!=text){ + object()->setProperty(propertyName().toLatin1(),stringToLocation(text)); + dynamic_cast(sender())->setTextValue(locationToString(object()->property(propertyName().toLatin1()).toInt())); + } +} diff --git a/src/items/lrsubitemparentpropitem.h b/src/items/lrsubitemparentpropitem.h new file mode 100644 index 0000000..9aa420e --- /dev/null +++ b/src/items/lrsubitemparentpropitem.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRSUBITEMPARENTPROPITEM_H +#define LRSUBITEMPARENTPROPITEM_H + +#include + +#include "lrobjectpropitem.h" +#include "lritemdesignintf.h" + +namespace LimeReport{ +class ItemLocationPropItem : public LimeReport::ObjectPropItem{ + Q_OBJECT +public: + ItemLocationPropItem():ObjectPropItem(){} + ItemLocationPropItem(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value, ObjectPropItem* parent, bool readonly); + QWidget* createProperyEditor(QWidget *parent) const; + QString displayValue() const; + void setPropertyEditorData(QWidget *, const QModelIndex &) const; + void setModelData(QWidget *, QAbstractItemModel *, const QModelIndex &); +private slots: + void slotLocationChanged(const QString& text); +private: + QString locationToString(LimeReport::ItemDesignIntf::LocationType location) const; + QString locationToString(int location) const {return locationToString(static_cast(location));} + LimeReport::ItemDesignIntf::LocationType stringToLocation(const QString& locationName); +private: + QMap m_locationMap; +}; +} +#endif // LRSUBITEMPARENTPROPITEM_H diff --git a/src/items/lrtextitem.cpp b/src/items/lrtextitem.cpp new file mode 100644 index 0000000..1a83a14 --- /dev/null +++ b/src/items/lrtextitem.cpp @@ -0,0 +1,504 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include +#include +#include +#include + +#include "lrpagedesignintf.h" +#include "lrtextitem.h" +#include "lrdesignelementsfactory.h" +#include "lrglobal.h" +#include "lrdatasourcemanager.h" +#include "lrsimpletagparser.h" +#include "lrtextitemeditor.h" +#include "lrreportengine_p.h" + +namespace{ + +const QString xmlTag = "TextItem"; + +LimeReport::BaseDesignIntf * createTextItem(QObject* owner, LimeReport::BaseDesignIntf* parent){ + return new LimeReport::TextItem(owner,parent); +} +bool registred = LimeReport::DesignElementsFactory::instance().registerCreator(xmlTag, LimeReport::ItemAttribs(QObject::tr("Text Item"),"TextItem"), createTextItem); + +} + +namespace LimeReport{ + +TextItem::TextItem(QObject *owner, QGraphicsItem *parent) + : ContentItemDesignIntf(xmlTag,owner,parent), m_angle(Angle0),m_trimValue(true){ + m_text = new QTextDocument(); + Init(); +} + +TextItem::TextItem(const QString& text, QObject* owner /*= 0*/, QGraphicsItem* parent /*= 0*/) + : ContentItemDesignIntf(xmlTag, owner,parent), m_angle(Angle0), m_trimValue(true){ + m_strText = text; + m_text = new QTextDocument(text); + m_text->setHtml(replaceReturns(m_strText)); + initText(); + Init(); +} + +TextItem::~TextItem() +{ + delete m_text; +} + +void TextItem::paint(QPainter* ppainter, const QStyleOptionGraphicsItem* style, QWidget* widget) { + Q_UNUSED(widget); + Q_UNUSED(style); + + ppainter->save(); + + setupPainter(ppainter); + prepareRect(ppainter,style,widget); + + QSizeF tmpSize = rect().size()-m_textSize; + + if ((tmpSize.height()>0) && (m_alignment & Qt::AlignVCenter)) //allow html + ppainter->translate(0,tmpSize.height()/2); + + if ((tmpSize.height()>0) && (m_alignment & Qt::AlignBottom)) // allow html + ppainter->translate(0,tmpSize.height()); + + if (!ppainter->clipRegion().isEmpty()){ + QRegion clipReg=ppainter->clipRegion().xored(ppainter->clipRegion().subtracted(rect().toRect())); + ppainter->setClipRegion(clipReg); + } else { + ppainter->setClipRect(rect()); + } + + switch (m_angle){ + case Angle90: + ppainter->translate(width(),0); + ppainter->rotate(90); + break; + case Angle180: + ppainter->translate(width(),height()); + ppainter->rotate(180); + break; + case Angle270: + ppainter->translate(0,height()); + ppainter->rotate(270); + break; + case Angle45: + ppainter->translate(width()/2,0); + ppainter->rotate(45); + m_text->setTextWidth(sqrt(2*(pow(width()/2,2)))); + break; + case Angle315: + ppainter->translate(0,height()/2); + ppainter->rotate(315); + m_text->setTextWidth(sqrt(2*(pow(height()/2,2)))); + break; + default: + break; + } + + for(QTextBlock it=m_text->begin();it!=m_text->end();it=it.next()){ + for (int i=0;ilineCount();i++){ + ppainter->setOpacity(qreal(foregroundOpacity())/100); + it.layout()->lineAt(i).draw(ppainter,QPointF(marginSize(),0)); + } + } + + +// m_layout.draw(ppainter,QPointF(marginSize(),0),); +// ppainter->setFont(transformToSceneFont(font())); +// QTextOption o; +// o.setAlignment(alignment()); +// ppainter->drawText(rect(), content(), o); + + ppainter->restore(); + BaseDesignIntf::paint(ppainter, style, widget); +} + +QString TextItem::content() const{ + return m_strText; +} + +void TextItem::Init() +{ + m_autoWidth=NoneAutoWidth; + m_alignment= Qt::AlignLeft|Qt::AlignTop; + m_autoHeight=false; + m_text->setDefaultFont(transformToSceneFont(font())); + m_textSize=QSizeF(); + m_foregroundOpacity = 100; +} + +void TextItem::setContent(const QString &value) +{ + if (m_strText.compare(value)!=0){ + QString oldValue = m_strText; + m_strText=value; + m_text->setHtml(replaceReturns(value.trimmed())); + m_text->setTextWidth(width()); + m_textSize=m_text->size(); + if (!isLoading()){ + update(rect()); + notify("content",oldValue,value); + //updateLayout(); + } + } +} + +void TextItem::updateItemSize(RenderPass pass, int /*maxHeight*/) +{ + if (isNeedExpandContent()) + expandContent(pass); + if (!isLoading()) + initText(); + + if (m_textSize.width()>width() && ((m_autoWidth==MaxWordLength)||(m_autoWidth==MaxStringLength))){ + setWidth(m_textSize.width()); + } + + if ((m_textSize.height()>height()) && (m_autoHeight) ){ + setHeight(m_textSize.height()+5); + } +} + +void TextItem::updateLayout() +{ + m_layout.setFont(transformToSceneFont(font())); + m_layout.setText(content()); + qreal linePos = 0; + m_layout.beginLayout(); + while(true){ + QTextLine line = m_layout.createLine(); + if (!line.isValid()) break; + line.setLineWidth(width()-marginSize()*2); + line.setPosition(QPoint(marginSize(),linePos)); + linePos+=line.height(); + } + m_layout.endLayout(); +} + +bool TextItem::isNeedExpandContent() const +{ + QRegExp rx("$*\\{[^{]*\\}"); + return content().contains(rx); +} + +QString TextItem::replaceBR(QString text) +{ + return text.replace("
","\n"); +} + +QString TextItem::replaceReturns(QString text) +{ + QString result = text.replace("\r\n","
"); + result = result.replace("\n","
"); + return result; +} + +void TextItem::initText() +{ + QTextOption to; + to.setAlignment(m_alignment); + + if (m_autoWidth!=MaxStringLength) + to.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); + else to.setWrapMode(QTextOption::NoWrap); + + m_text->setDocumentMargin(marginSize()); + m_text->setDefaultTextOption(to); + m_text->setDefaultFont(transformToSceneFont(font())); + if ((m_angle==Angle0)||(m_angle==Angle180)){ + m_text->setTextWidth(rect().width()); + } else { + m_text->setTextWidth(rect().height()); + } + m_textSize=m_text->size(); +} +bool TextItem::trimValue() const +{ + return m_trimValue; +} + +void TextItem::setTrimValue(bool trimValue) +{ + m_trimValue = trimValue; +} + + +void TextItem::geometryChangedEvent(QRectF , QRectF) +{ + if ((m_angle==Angle0)||(m_angle==Angle180)){ + m_text->setTextWidth(rect().width()); + } else { + m_text->setTextWidth(rect().height()); + } + m_textSize=m_text->size(); +} + +bool TextItem::isNeedUpdateSize(RenderPass pass) const +{ + Q_UNUSED(pass) + bool res = (m_textSize.height()>geometry().height()&&autoHeight()) || + (m_textSize.width()>geometry().width()&&autoWidth()) || + isNeedExpandContent(); + return res; +} + +//void TextItem::setMarginSize(int value) +//{ +// if (m_margin!=value){ +// int oldValue = m_margin; +// m_margin=value; +// if (!isLoading()){ +// update(rect()); +// notify("margin", oldValue, value); +// } +// } +//} + +void TextItem::setAlignment(Qt::Alignment value) +{ + if (m_alignment!=value){ + Qt::Alignment oldValue = m_alignment; + m_alignment=value; + m_layout.setTextOption(QTextOption(m_alignment)); + if (!isLoading()){ + initText(); + update(rect()); + notify("alignment",QVariant(oldValue),QVariant(value)); + } + } +} + +void TextItem::expandContent(RenderPass pass) +{ + QString context=content(); + switch(pass){ + case FirstPass: + context=expandUserVariables(context, pass, NoEscapeSymbols); + context=expandScripts(context); + context=expandDataFields(context, NoEscapeSymbols); + break; + case SecondPass:; + context=expandUserVariables(context, pass, NoEscapeSymbols); + context=expandScripts(context); + } + + setContent(context); +} + +void TextItem::setAutoHeight(bool value) +{ + if (m_autoHeight!=value){ + bool oldValue = m_autoHeight; + m_autoHeight=value; + notify("autoHeight",oldValue,value); + } +} + +void TextItem::setAutoWidth(TextItem::AutoWidth value) +{ + if (m_autoWidth!=value){ + TextItem::AutoWidth oldValue = m_autoWidth; + m_autoWidth=value; + notify("autoWidth",oldValue,value); + } +} + +bool TextItem::canBeSplitted(int height) const +{ + return height>(m_text->begin().layout()->lineAt(0).height()); +} + +BaseDesignIntf *TextItem::cloneUpperPart(int height, QObject *owner, QGraphicsItem *parent) +{ + int linesHeight=0; + initText(); + QString tmpText=""; + TextItem* upperPart = dynamic_cast(cloneItem(itemMode(),owner,parent)); + + for (QTextBlock it=m_text->begin();it!=m_text->end();it=it.next()){ + for (int i=0;ilineCount();i++){ + linesHeight+=it.layout()->lineAt(i).height(); + if (linesHeight>(height-(marginSize()*2))) {linesHeight-=it.layout()->lineAt(i).height(); goto loop_exit;} + tmpText+=it.text().mid(it.layout()->lineAt(i).textStart(),it.layout()->lineAt(i).textLength())+'\n'; + } + } + loop_exit: + upperPart->setHeight(linesHeight+marginSize()*2); + QScopedPointer context(new HtmlContext(m_strText)); + upperPart->setContent(context->extendTextByTags(tmpText,0)); + return upperPart; +} + +BaseDesignIntf *TextItem::cloneBottomPart(int height, QObject *owner, QGraphicsItem *parent) +{ + TextItem* bottomPart = dynamic_cast(cloneItem(itemMode(),owner,parent)); + int linesHeight=0; + int curLine=0; + QTextBlock curBlock; + + QString tmpText=""; + + for (curBlock=m_text->begin();curBlock!=m_text->end();curBlock=curBlock.next()){ + for (curLine=0;curLinelineCount();curLine++){ + linesHeight+=curBlock.layout()->lineAt(curLine).height(); + if (linesHeight>(height-(marginSize()*2))) {goto loop_exit;} + } + } + loop_exit:; + int textPos=0; + for (;curBlock!=m_text->end();curBlock=curBlock.next()){ + for (;curLinelineCount();curLine++){ + if (tmpText=="") textPos= curBlock.layout()->lineAt(curLine).textStart(); + tmpText+=curBlock.text().mid(curBlock.layout()->lineAt(curLine).textStart(), + curBlock.layout()->lineAt(curLine).textLength())+"\n"; + } + } + + QScopedPointer context(new HtmlContext(m_strText)); + bottomPart->setContent(context->extendTextByTags(tmpText,textPos)); + bottomPart->setHeight(bottomPart->m_textSize.height()+5); + return bottomPart; +} + +BaseDesignIntf *TextItem::createSameTypeItem(QObject *owner, QGraphicsItem *parent) +{ + return new TextItem(owner,parent); +} + +BaseDesignIntf *TextItem::cloneEmpty(int height, QObject *owner, QGraphicsItem *parent) +{ + TextItem* empty=dynamic_cast(cloneItem(itemMode(),owner,parent)); + empty->setContent(""); + empty->setHeight(height); + return empty; +} + +void TextItem::objectLoadFinished() +{ + ItemDesignIntf::objectLoadFinished(); + initText(); +} + +void TextItem::setTextItemFont(QFont value) +{ + if (font()!=value){ + QFont oldValue = font(); + setFont(value); + m_text->setDefaultFont(transformToSceneFont(value)); + notify("font",oldValue,value); + } +} + +QWidget *TextItem::defaultEditor() +{ + QSettings* l_settings = (page()->settings() != 0) ? + page()->settings() : + (page()->reportEditor()!=0) ? page()->reportEditor()->settings() : 0; + QWidget* editor = new TextItemEditor(this,page(),l_settings); + editor->setAttribute(Qt::WA_DeleteOnClose); + return editor; +} + +void TextItem::setBackgroundOpacity(int value) +{ + if (opacity()!=value){ + int oldValue = opacity(); + setOpacity(value); + notify("backgroundOpacity",oldValue,value); + } +} + +void TextItem::setBackgroundModeProperty(BaseDesignIntf::BGMode value) +{ + if (value!=backgroundMode()){ + BaseDesignIntf::BGMode oldValue = backgroundMode(); + setBackgroundMode(value); + notify("backgroundMode",oldValue,value); + } +} + +void TextItem::setBackgroundColorProperty(QColor value) +{ + if(value!=backgroundColor()){ + QColor oldValue = backgroundColor(); + setBackgroundColor(value); + notify("backgroundMode",oldValue,value); + } +} + +void TextItem::setFontColorProperty(QColor value) +{ + if(value!=fontColor()){ + QColor oldValue = fontColor(); + setFontColor(value); + notify("fontColor",oldValue,value); + } +} + +TextItem::AngleType TextItem::angle() const +{ + return m_angle; +} + +void TextItem::setAngle(const AngleType& value) +{ + if (m_angle!=value){ + AngleType oldValue = m_angle; + m_angle = value; + if (!isLoading()){ + initText(); + update(); + notify("angle",oldValue,value); + } + } +} + +void TextItem::setForegroundOpacity(int value) +{ + if (value>100){ + value=100; + } else if(value<0){ + value=0; + } + if (m_foregroundOpacity != value){ + int oldValue = m_foregroundOpacity; + m_foregroundOpacity = value; + update(); + notify("foregroundOpacity",oldValue,value); + } +} + +} //namespace LimeReport + + + diff --git a/src/items/lrtextitem.h b/src/items/lrtextitem.h new file mode 100644 index 0000000..f2e2abe --- /dev/null +++ b/src/items/lrtextitem.h @@ -0,0 +1,136 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRTEXTITEM_H +#define LRTEXTITEM_H +#include +#include +#include +#include "lritemdesignintf.h" +#include + +#include + +namespace LimeReport { + +class Tag; +class TextItem : public LimeReport::ContentItemDesignIntf { + Q_OBJECT + Q_ENUMS(AutoWidth) + Q_ENUMS(AngleType) + Q_PROPERTY(QString content READ content WRITE setContent) + Q_PROPERTY(int margin READ marginSize WRITE setMarginSize) + Q_PROPERTY(Qt::Alignment alignment READ alignment() WRITE setAlignment) + Q_PROPERTY(AutoWidth autoWidth READ autoWidth() WRITE setAutoWidth) + Q_PROPERTY(bool autoHeight READ autoHeight() WRITE setAutoHeight) + Q_PROPERTY(QFont font READ font() WRITE setTextItemFont) + Q_PROPERTY(int backgroundOpacity READ opacity WRITE setBackgroundOpacity) + Q_PROPERTY(BGMode backgroundMode READ backgroundMode WRITE setBackgroundModeProperty) + Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColorProperty) + Q_PROPERTY(QColor fontColor READ fontColor WRITE setFontColorProperty) + Q_PROPERTY(AngleType angle READ angle WRITE setAngle) + Q_PROPERTY(int foregroundOpacity READ foregroundOpacity WRITE setForegroundOpacity()) + Q_PROPERTY(bool trimValue READ trimValue WRITE setTrimValue) +public: + + enum AutoWidth{NoneAutoWidth,MaxWordLength,MaxStringLength}; + enum AngleType{Angle0,Angle90,Angle180,Angle270,Angle45,Angle315}; + + void Init(); + TextItem(QObject* owner,QGraphicsItem* parent); + TextItem(const QString& content,QObject* owner = 0, QGraphicsItem* parent = 0); + ~TextItem(); + + void paint(QPainter* ppainter, const QStyleOptionGraphicsItem*, QWidget*); + QString content() const; + void setContent(const QString& value); + + //void setMarginSize(int value); + + + void setAlignment(Qt::Alignment value); + Qt::Alignment alignment(){return m_alignment;} + + virtual void geometryChangedEvent(QRectF, QRectF); + virtual bool isNeedUpdateSize(RenderPass) const; + virtual void updateItemSize(RenderPass pass, int); + void expandContent(RenderPass pass); + + void setAutoHeight(bool value); + bool autoHeight() const {return m_autoHeight;} + + void setAutoWidth(AutoWidth value); + AutoWidth autoWidth() const {return m_autoWidth;} + + bool canBeSplitted(int height) const; + bool isSplittable() const { return true;} + bool isEmpty() const{return m_text->isEmpty();} + BaseDesignIntf* cloneUpperPart(int height, QObject *owner, QGraphicsItem *parent); + BaseDesignIntf* cloneBottomPart(int height, QObject *owner, QGraphicsItem *parent); + BaseDesignIntf* createSameTypeItem(QObject* owner=0, QGraphicsItem* parent=0); + BaseDesignIntf* cloneEmpty(int height, QObject *owner, QGraphicsItem *parent); + void objectLoadFinished(); + + void setTextItemFont(QFont value); + virtual QWidget* defaultEditor(); + void setBackgroundOpacity(int value); + void setBackgroundModeProperty(BGMode value); + void setBackgroundColorProperty(QColor value); + void setFontColorProperty(QColor value); + AngleType angle() const; + void setAngle(const AngleType& value); + int foregroundOpacity(){return m_foregroundOpacity;} + void setForegroundOpacity(int value); + + bool trimValue() const; + void setTrimValue(bool trimValue); + +protected: + void updateLayout(); + bool isNeedExpandContent() const; + QString replaceBR(QString text); + QString replaceReturns(QString text); +private: + void initText(); +private: + QString m_strText; + + QTextLayout m_layout; + QTextDocument* m_text; + Qt::Alignment m_alignment; + bool m_autoHeight; + AutoWidth m_autoWidth; + QSizeF m_textSize; + AngleType m_angle; + int m_foregroundOpacity; + bool m_trimValue; +}; + +} +#endif // LRTEXTITEM_H diff --git a/src/items/lrtextitemeditor.cpp b/src/items/lrtextitemeditor.cpp new file mode 100644 index 0000000..1d8842e --- /dev/null +++ b/src/items/lrtextitemeditor.cpp @@ -0,0 +1,356 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrtextitemeditor.h" +#include "ui_lrtextitemeditor.h" + +#include "lrdatasourcemanager.h" +#include "lrscriptenginemanager.h" +#include "lrdatadesignintf.h" +#include "lrdatasourcemanager.h" +#include +#include + +TextItemEditor::TextItemEditor(LimeReport::TextItem *item, LimeReport::PageDesignIntf *page, QSettings* settings, QWidget *parent) : + QWidget(parent), + ui(new Ui::TextItemEditor), m_textItem(item), m_page(page), m_settings(settings), m_ownedSettings(false), m_isReadingSetting(false) +{ + ui->setupUi(this); + initUI(); + m_teContent->setPlainText(item->content()); + m_teContent->setFocus(); + setWindowIcon(QIcon(":/items/images/TextItem")); + readSetting(); +} + +TextItemEditor::~TextItemEditor() +{ +#ifdef Q_OS_WIN + writeSetting(); +#endif +#ifdef Q_OS_MAC + writeSetting(); +#endif + delete ui; +} + +void TextItemEditor::setSettings(QSettings* value) +{ + if (m_ownedSettings) + delete m_settings; + m_settings=value; + m_ownedSettings=false; + readSetting(); +} + +QSettings*TextItemEditor::settings() +{ + if (m_settings){ + return m_settings; + } else { + m_settings = new QSettings("LimeReport",QApplication::applicationName()); + m_ownedSettings = true; + return m_settings; + } +} + +void TextItemEditor::resizeEvent(QResizeEvent*) +{ +#ifdef Q_OS_UNIX + writeSetting(); +#endif +} + +void TextItemEditor::moveEvent(QMoveEvent*) +{ +#ifdef Q_OS_UNIX + writeSetting(); +#endif +} + +void TextItemEditor::on_pbOk_clicked() +{ + if (m_textItem->content()!=m_teContent->toPlainText()){ + m_textItem->setContent(m_teContent->toPlainText()); + } + close(); +} + +void TextItemEditor::initUI() +{ + QStringList dataWords; + m_teContent = ui->textEdit; + m_completer = new QCompleter(this); + m_teContent->setCompleter(m_completer); + + m_datasourcesMenu = new QMenu(this); + + LimeReport::DataSourceManager* dm = LimeReport::DataSourceManager::instance(); + if (dm){ + ui->twData->setModel(dm->datasourcesModel()); + ui->twScriptEngine->setModel(LimeReport::ScriptEngineManager::instance().model()); + + foreach(QString dsName,dm->dataSourceNames()){ + foreach(QString field, dm->fieldNames(dsName)){ + dataWords<tabWidget->setVisible(false); + } + + LimeReport::ScriptEngineManager& se = LimeReport::ScriptEngineManager::instance(); + + foreach (LimeReport::ScriptFunctionDesc functionDesc, se.functionsDescriber()) { + dataWords<setModel(new QStringListModel(dataWords,m_completer)); + ui->gbSettings->setVisible(false); +} + +QStringListModel *TextItemEditor::getDataSources() +{ + LimeReport::DataSourceManager* dm= LimeReport::DataSourceManager::instance(); + QStringList dataSources; + foreach(QString dsName,dm->dataSourceNames()){ + dataSources<fieldNames(datasource)){ + fields<(sender()); + m_teContent->insertPlainText(action->whatsThis()); +} + +void TextItemEditor::readSetting() +{ + if (settings()==0) return; + + m_isReadingSetting = true; + + settings()->beginGroup("TextItemEditor"); + QVariant v = settings()->value("Geometry"); + if (v.isValid()){ + restoreGeometry(v.toByteArray()); + } + v = settings()->value("State"); + if (v.isValid()){ + ui->splitter->restoreState(v.toByteArray()); + } + + QVariant fontName = settings()->value("FontName"); + if (fontName.isValid()){ + QVariant fontSize = settings()->value("FontSize"); + ui->textEdit->setFont(QFont(fontName.toString(),fontSize.toInt())); + ui->editorFont->setCurrentFont(ui->textEdit->font()); + ui->editorFontSize->setValue(fontSize.toInt()); + } + settings()->endGroup(); + + m_isReadingSetting = false; +} + +void TextItemEditor::writeSetting() +{ + if (settings()!=0){ + settings()->beginGroup("TextItemEditor"); + settings()->setValue("Geometry",saveGeometry()); + settings()->setValue("State",ui->splitter->saveState()); + settings()->endGroup(); + } +} + + +CompleaterTextEditor::CompleaterTextEditor(QWidget *parent) + : QTextEdit(parent),m_compleater(0) +{ +} + +void CompleaterTextEditor::setCompleter(QCompleter *value) +{ + if (value) disconnect(value,0,this,0); + m_compleater = value; + if (!m_compleater) return; + m_compleater->setWidget(this); + m_compleater->setCompletionMode(QCompleter::PopupCompletion); + m_compleater->setCaseSensitivity(Qt::CaseInsensitive); + connect(m_compleater,SIGNAL(activated(QString)),this,SLOT(insertCompletion(QString))); +} + +void CompleaterTextEditor::keyPressEvent(QKeyEvent *e) +{ + if (m_compleater && m_compleater->popup()->isVisible()) { + switch (e->key()) { + case Qt::Key_Enter: + case Qt::Key_Return: + case Qt::Key_Escape: + case Qt::Key_Tab: + case Qt::Key_Backtab: + e->ignore(); + return; + default: + break; + } + } + + bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_E); + if (!m_compleater || !isShortcut) QTextEdit::keyPressEvent(e); + + const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier); + if (!m_compleater || (ctrlOrShift && e->text().isEmpty())) + return; + + static QString eow("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="); // end of word + bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift; + + QString completionPrefix = textUnderCursor(); + + if (!isShortcut && (hasModifier || e->text().isEmpty()|| completionPrefix.length() < 3 + || eow.contains(e->text().right(1)))) { + m_compleater->popup()->hide(); + return; + } + + if (completionPrefix != m_compleater->completionPrefix()) { + m_compleater->setCompletionPrefix(completionPrefix); + m_compleater->popup()->setCurrentIndex(m_compleater->completionModel()->index(0, 0)); + } + + QRect cr = cursorRect(); + cr.setWidth(m_compleater->popup()->sizeHintForColumn(0) + + m_compleater->popup()->verticalScrollBar()->sizeHint().width()); + m_compleater->complete(cr); + +} + +void CompleaterTextEditor::focusInEvent(QFocusEvent *e) +{ + if (m_compleater) m_compleater->setWidget(this); + QTextEdit::focusInEvent(e); +} + +QString CompleaterTextEditor::textUnderCursor() const +{ + QTextCursor tc = textCursor(); + tc.select(QTextCursor::WordUnderCursor); + return tc.selectedText(); +} + + +void CompleaterTextEditor::insertCompletion(const QString &completion) +{ + if (m_compleater->widget() != this) + return; + QTextCursor tc = textCursor(); + int extra = completion.length() - m_compleater->completionPrefix().length(); + tc.movePosition(QTextCursor::Left); + tc.movePosition(QTextCursor::EndOfWord); + tc.insertText(completion.right(extra)); + setTextCursor(tc); +} + +void TextItemEditor::on_twData_doubleClicked(const QModelIndex &index) +{ + if (!index.isValid()) return; + LimeReport::DataNode* node = static_cast(index.internalPointer()); + if (node->type()==LimeReport::DataNode::Field){ + m_teContent->insertPlainText(QString("$D{%1.%2}").arg(node->parent()->name()).arg(node->name())); + } + if (node->type()==LimeReport::DataNode::Variable){ + m_teContent->insertPlainText(QString("$V{%1}").arg(node->name())); + } +} + +void TextItemEditor::on_twScriptEngine_doubleClicked(const QModelIndex &index) +{ + if (!index.isValid()) return; + LimeReport::ScriptEngineNode* node = static_cast(index.internalPointer()); + if (node->type()==LimeReport::ScriptEngineNode::Function){ + m_teContent->insertPlainText(node->name()+"()"); + } +} + +void TextItemEditor::on_splitter_splitterMoved(int , int ) +{ +#ifdef unix + writeSetting(); +#endif +} + +void TextItemEditor::on_editorFont_currentFontChanged(const QFont &f) +{ + if (m_isReadingSetting) return; + QFont tmp = f; + tmp.setPointSize(ui->editorFontSize->value()); + ui->textEdit->setFont(tmp); + settings()->beginGroup("TextItemEditor"); + settings()->setValue("FontName",ui->textEdit->font().family()); + settings()->setValue("FontSize",ui->editorFontSize->value()); + settings()->endGroup(); +} + +void TextItemEditor::on_editorFontSize_valueChanged(int arg1) +{ + if (m_isReadingSetting) return; + ui->textEdit->setFont(QFont(ui->textEdit->font().family(),arg1)); + settings()->beginGroup("TextItemEditor"); + settings()->setValue("FontName",ui->textEdit->font().family()); + settings()->setValue("FontSize",ui->editorFontSize->value()); + settings()->endGroup(); +} + +void TextItemEditor::on_toolButton_clicked(bool checked) +{ + ui->gbSettings->setVisible(checked); +} diff --git a/src/items/lrtextitemeditor.h b/src/items/lrtextitemeditor.h new file mode 100644 index 0000000..e6ce2f5 --- /dev/null +++ b/src/items/lrtextitemeditor.h @@ -0,0 +1,106 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRTEXTITEMEDITOR_H +#define LRTEXTITEMEDITOR_H + +#include +#include +#include + +#include "lrtextitem.h" +#include "lrpagedesignintf.h" + +namespace Ui { +class TextItemEditor; +} + +class CompleaterTextEditor :public QTextEdit +{ + Q_OBJECT +public: + CompleaterTextEditor(QWidget* parent=0); + void setCompleter(QCompleter* value); + QCompleter* compleater() const{ return m_compleater;} +protected: + virtual void keyPressEvent(QKeyEvent *e); + virtual void focusInEvent(QFocusEvent *e); +private: + QString textUnderCursor() const; +private slots: + void insertCompletion(const QString& completion); +private: + QCompleter* m_compleater; +}; + +class TextItemEditor : public QWidget +{ + Q_OBJECT +public: + explicit TextItemEditor(LimeReport::TextItem* item, LimeReport::PageDesignIntf* page, + QSettings* settings=0, QWidget *parent = 0); + ~TextItemEditor(); + void setSettings(QSettings* value); + QSettings* settings(); +protected: + void resizeEvent(QResizeEvent *); + void moveEvent(QMoveEvent *); +private slots: + void on_pbOk_clicked(); + void on_pbCancel_clicked(); + void slotFieldSelected(); + void on_twData_doubleClicked(const QModelIndex &index); + void on_twScriptEngine_doubleClicked(const QModelIndex &index); + void on_splitter_splitterMoved(int, int); + void on_editorFont_currentFontChanged(const QFont &f); + + void on_editorFontSize_valueChanged(int arg1); + + void on_toolButton_clicked(bool checked); + +private: + void initUI(); + void readSetting(); + void writeSetting(); + QStringListModel* getDataSources(); + QStringListModel* getPrefixes(); + QStringListModel* getColumns(QString datasource); +private: + Ui::TextItemEditor *ui; + LimeReport::TextItem* m_textItem; + LimeReport::PageDesignIntf* m_page; + QMenu* m_datasourcesMenu; + CompleaterTextEditor* m_teContent; + QCompleter* m_completer; + QSettings* m_settings; + bool m_ownedSettings; + bool m_isReadingSetting; +}; + +#endif // LRTEXTITEMEDITOR_H diff --git a/src/items/lrtextitemeditor.ui b/src/items/lrtextitemeditor.ui new file mode 100644 index 0000000..0934c90 --- /dev/null +++ b/src/items/lrtextitemeditor.ui @@ -0,0 +1,251 @@ + + + TextItemEditor + + + Qt::ApplicationModal + + + + 0 + 0 + 539 + 436 + + + + Text Item Editor + + + + :/items/images/insert-text_3.png:/items/images/insert-text_3.png + + + + + + + 0 + 0 + + + + Content + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + + 12 + + + + + + QTabWidget::South + + + 0 + + + + Data + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + false + + + + + + + + Functions + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + false + + + + + + + + + + + + + + + Editor settings + + + + + + + + Editor font + + + + + + + + + + 11 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + ... + + + + :/items/images/settings.png:/items/images/settings.png + + + true + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Ok + + + + + + + Cancel + + + Esc + + + + + + + + + + CompleaterTextEditor + QTextEdit +
lrtextitemeditor.h
+
+
+ + pbOk + pbCancel + + + + + +
diff --git a/src/lraboutdialog.cpp b/src/lraboutdialog.cpp new file mode 100644 index 0000000..cd7fc6c --- /dev/null +++ b/src/lraboutdialog.cpp @@ -0,0 +1,44 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lraboutdialog.h" +#include "ui_lraboutdialog.h" + +AboutDialog::AboutDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::AboutDialog) +{ + ui->setupUi(this); + ui->lblVersion->setText(QString("Version %1").arg(LIMEREPORT_VERSION_STR)); +} + +AboutDialog::~AboutDialog() +{ + delete ui; +} diff --git a/src/lraboutdialog.h b/src/lraboutdialog.h new file mode 100644 index 0000000..f738719 --- /dev/null +++ b/src/lraboutdialog.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRABOUTDIALOG_H +#define LRABOUTDIALOG_H + +#include + +namespace Ui { +class AboutDialog; +} + +class AboutDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AboutDialog(QWidget *parent = 0); + ~AboutDialog(); + +private: + Ui::AboutDialog *ui; +}; + +#endif // LRABOUTDIALOG_H diff --git a/src/lraboutdialog.ui b/src/lraboutdialog.ui new file mode 100644 index 0000000..8007db3 --- /dev/null +++ b/src/lraboutdialog.ui @@ -0,0 +1,264 @@ + + + AboutDialog + + + + 0 + 0 + 661 + 359 + + + + About + + + + + + 0 + + + + Lime Report + + + + + + true + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/report/images/logo_100.png" height="100" style="float: left;" /><span style=" font-size:12pt; font-weight:600; color:#555555;">Report engine for </span><span style=" font-size:12pt; font-weight:600; color:#7faa18;">Qt</span><span style=" font-size:12pt; font-weight:600; color:#555555;"> framework</span></p> +<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">LimeReport - multi-platform C++ library written using Qt framework and intended for software developers that would like to add into their application capability to form report or print forms generated using templates.</span></p> +<p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> +<p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> +<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">Official web site : </span><a href="www.limereport.ru"><span style=" font-size:11pt; text-decoration: underline; color:#0000ff;">www.limereport.ru</span></a></p> +<p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt; text-decoration: underline; color:#0000ff;"><br /></p> +<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600; color:#000000;">This library 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.</span></p> +<p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt; font-weight:600; color:#000000;"><br /></p> +<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; color:#000000;">Copyright 2015 Arin Alexander. All rights reserved.</span></p></body></html> + + + + + + + + Author + + + + + + true + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Arin Alexander</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">arin_a@bk.ru</p></body></html> + + + + + + + + License + + + + + + true + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">(c) 2015 Arin Alexander arin_a@bk.ru</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">GNU GENERAL PUBLIC LICENSE</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Version 3, 29 June 2007 </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Preamble </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The GNU General Public License is a free, copyleft license for software and other kinds of works. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The precise terms and conditions for copying, distribution and modification follow. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TERMS AND CONDITIONS </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">0. Definitions. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">“This License” refers to version 3 of the GNU General Public License. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">“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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">A “covered work” means either the unmodified Program or a work based on the Program. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1. Source Code. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The Corresponding Source for a work in source code form is that same work. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">2. Basic Permissions. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">3. Protecting Users' Legal Rights From Anti-Circumvention Law. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">4. Conveying Verbatim Copies. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">5. Conveying Modified Source Versions. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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: </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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”. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">6. Conveying Non-Source Forms. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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: </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">“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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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). </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">7. Additional Terms. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">“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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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: </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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 </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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 </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">8. Termination. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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). </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">9. Acceptance Not Required for Having Copies. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">10. Automatic Licensing of Downstream Recipients. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">11. Patents. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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”. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">12. No Surrender of Others' Freedom. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">13. Use with the GNU Affero General Public License. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">14. Revised Versions of this License. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">15. Disclaimer of Warranty. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">16. Limitation of Liability. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">17. Interpretation of Sections 15 and 16. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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. </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">END OF TERMS AND CONDITIONS </p></body></html> + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Close + + + + + + + + + Version 0.1.1 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + pushButton + clicked() + AboutDialog + accept() + + + 607 + 340 + + + 367 + 323 + + + + + diff --git a/src/lrbanddesignintf.cpp b/src/lrbanddesignintf.cpp new file mode 100644 index 0000000..9787234 --- /dev/null +++ b/src/lrbanddesignintf.cpp @@ -0,0 +1,729 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrbanddesignintf.h" +#include "lritemdesignintf.h" +#include "lrglobal.h" +#include +#include + +namespace LimeReport { + +BandMarker::BandMarker(BandDesignIntf *band, QGraphicsItem* parent) + :QGraphicsItem(parent),m_rect(0,0,30,30),m_band(band) +{} + +QRectF BandMarker::boundingRect() const +{ + return m_rect; +} + +void BandMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem* /**option*/, QWidget* /*widget*/) +{ + painter->save(); + painter->setOpacity(BAND_MARKER_OPACITY); + painter->fillRect(boundingRect(),m_color); + painter->setOpacity(1); + painter->setRenderHint(QPainter::Antialiasing); + qreal size = (boundingRect().width()setBrush(Qt::white); + painter->setPen(Qt::white); + painter->drawEllipse(r.adjusted(5,5,-5,-5)); + if (m_band->isSelected()){ + painter->setBrush(m_color); + painter->drawEllipse(r.adjusted(7,7,-7,-7)); + } + painter->restore(); +} + +void BandMarker::setHeight(qreal height) +{ + if (m_rect.height()!=height){ + prepareGeometryChange(); + m_rect.setHeight(height); + } +} + +void BandMarker::setWidth(qreal width) +{ + if (m_rect.width()!=width){ + prepareGeometryChange(); + m_rect.setWidth(width); + } +} + +void BandMarker::setColor(QColor color) +{ + if (m_color!=color){ + m_color = color; + update(boundingRect()); + } +} + +void BandMarker::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (event->button()==Qt::LeftButton) { + if (!(event->modifiers() & Qt::ControlModifier)) + m_band->scene()->clearSelection(); + m_band->setSelected(true); + update(0,0,boundingRect().width(),boundingRect().width()); + } +} + +bool Segment::intersect(Segment value) +{ + return ((value.m_end>=m_begin)&&(value.m_end<=m_end)) || + ((value.m_begin>=m_begin)&&(value.m_end>=m_end)) || + ((value.m_begin>=m_begin)&&(value.m_end<=m_end)) || + ((value.m_beginm_end)) ; +} + +qreal Segment::intersectValue(Segment value) +{ + if ((value.m_end>=m_begin)&&(value.m_end<=m_end)){ + return value.m_end-m_begin; + } + if ((value.m_begin>=m_begin)&&(value.m_end>=m_end)){ + return m_end-value.m_begin; + } + if ((value.m_begin>=m_begin)&&(value.m_end<=m_end)){ + return value.m_end-value.m_begin; + } + if ((value.m_beginm_end)){ + return m_end-m_begin; + } + return 0; +} + +BandDesignIntf::BandDesignIntf(BandsType bandType, const QString &xmlTypeName, QObject* owner, QGraphicsItem *parent) : + BaseDesignIntf(xmlTypeName, owner,parent), + m_bandType(bandType), + m_bandIndex(static_cast(bandType)), + m_dataSourceName(""), + m_autoHeight(true), + m_keepBottomSpace(false), + m_parentBand(0), + m_parentBandName(""), + m_bandMarker(0), + m_tryToKeepTogether(false), + m_splitable(false), + m_keepFooterTogether(false), + m_maxScalePercent(0), + m_sliceLastRow(false), + m_printIfEmpty(false) +{ + setPosibleResizeDirectionFlags(ResizeBottom); + setPosibleMoveFlags(TopBotom); + + if (parent) { + BaseDesignIntf* parentItem = dynamic_cast(parent); + if (parentItem) setWidth(parentItem->width()); + } + + setHeight(100); + setFixedPos(true); + setFlag(QGraphicsItem::ItemClipsChildrenToShape); + m_bandMarker = new BandMarker(this); + m_bandMarker->setColor(Qt::magenta); + m_bandMarker->setHeight(height()); + m_bandMarker->setPos(pos().x()-m_bandMarker->width(),pos().y()); + if (scene()) scene()->addItem(m_bandMarker); +} + +BandDesignIntf::~BandDesignIntf() +{ +// if (itemMode()&DesignMode){ +// foreach(BandDesignIntf* band,childBands()) { +// removeChildBand(band); +// delete band; +// } +// } + + if (m_bandMarker) { + delete m_bandMarker; + } +} + +void BandDesignIntf::paint(QPainter *ppainter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + if (backgroundColor()!=Qt::white) { + ppainter->fillRect(rect(),backgroundColor()); + } + if (itemMode()&DesignMode){ + ppainter->save(); + QString bandText = objectName(); + if (parentBand()) bandText+=QLatin1String(" connected to ")+parentBand()->objectName(); + QFont font("Arial",7*fontFACTOR,-1,true); + QFontMetrics fontMetrics(font); + + QVector bandNameRects; + bandNameRects.push_back(QRectF(8,8,fontMetrics.width(" "+bandText+" "),fontMetrics.height())); + //bandNameRects.push_back(QRectF(width()-fontMetrics.width(" "+bandText+" "),2,fontMetrics.width(" "+bandText+" "),fontMetrics.height())); + //bandNameRects.push_back(QRectF(2,height()-fontMetrics.height(),fontMetrics.width(" "+bandText+" "),fontMetrics.height())); + //bandNameRects.push_back(QRectF(width()-fontMetrics.width(" "+bandText+" "),height()-fontMetrics.height(),fontMetrics.width(" "+bandText+" "),fontMetrics.height())); + //if (bandNameRects[0].intersects(bandNameRects[2])) bandNameRects.remove(2,2); + //if (isSelected()) ppainter->setPen(QColor(167,244,167)); + // else ppainter->setPen(QColor(220,220,220)); + + ppainter->setFont(font); + for (int i=0;isetRenderHint(QPainter::Antialiasing); + ppainter->setBrush(bandColor()); + ppainter->setOpacity(BAND_NAME_AREA_OPACITY); + ppainter->drawRoundedRect(labelRect,8,8); + ppainter->setOpacity(BAND_NAME_TEXT_OPACITY); + ppainter->setPen(Qt::black); + ppainter->drawText(bandNameRects[i]," "+bandText+" "); + } + } + ppainter->restore(); + } + BaseDesignIntf::paint(ppainter,option,widget); +} + +BandDesignIntf::BandsType BandDesignIntf::bandType() const +{ + return m_bandType; +} + +QString BandDesignIntf::bandTitle() const +{ + return m_bandTypeText; +} + +QIcon BandDesignIntf::bandIcon() const +{ + return QIcon(); +} + +int BandDesignIntf::bandIndex() const +{ + return m_bandIndex; +} + +void BandDesignIntf::setBandIndex(int value) +{ + m_bandIndex=value; +} + +bool BandDesignIntf::isUnique() const +{ + return true; +} + +QString BandDesignIntf::datasourceName(){ + return m_dataSourceName; +} + +void BandDesignIntf::setDataSourceName(const QString &datasource){ + m_dataSourceName=datasource; +} + +void BandDesignIntf::addChildBand(BandDesignIntf *band) +{ + m_childBands.append(band); + connect(band,SIGNAL(destroyed(QObject*)),this,SLOT(childBandDeleted(QObject*))); +} + +void BandDesignIntf::removeChildBand(BandDesignIntf *band) +{ + m_childBands.removeAt(m_childBands.indexOf(band)); +} + +void BandDesignIntf::setParentBand(BandDesignIntf *band) +{ + m_parentBand=band; + if (band){ + if (parentBandName().compare(band->objectName(),Qt::CaseInsensitive)!=0) + setParentBandName(band->objectName()); + band->addChildBand(this); + } +} + +void BandDesignIntf::setParentBandName(const QString &parentBandName) +{ + m_parentBandName=parentBandName; + if (itemMode()&DesignMode && !m_parentBandName.isEmpty()){ + if ((parentBand()==0)||(parentBand()->objectName()!=parentBandName)) + setParentBand( findParentBand()); + } +} + +bool BandDesignIntf::isConnectedToBand(BandDesignIntf::BandsType bandType) const +{ + foreach(BandDesignIntf* band,childBands()) if (band->bandType()==bandType) return true; + return false; +} + +int BandDesignIntf::maxChildIndex(QSet bandTypes) const +{ + if (childBands().isEmpty()) return bandIndex(); + else{ + int curIndex=-1; + BandDesignIntf* curBand=0; + foreach(BandDesignIntf* band,childBands()){ + if (curIndexbandIndex()&&bandTypes.contains(band->bandType())){ + curIndex=band->bandIndex();curBand=band; + } + } + return (curBand)?std::max(curBand->maxChildIndex(bandTypes),bandIndex()):bandIndex(); + } +} + +int BandDesignIntf::groupFooterIndex(int groupHeaderIndex) +{ + foreach(BandDesignIntf* band, childBands()){ + if ((band->bandType()==BandDesignIntf::GroupHeader)&& + (band->bandIndex()>groupHeaderIndex)&& + (band->hasChildren()) + ){ + return dynamic_cast(band->childBands().at(0))->bandIndex(); + } + } + return maxChildIndex(subdetailBands()); +} + +int BandDesignIntf::groupHeaderIndex() +{ + int index=bandIndex(); + foreach(BandDesignIntf* band, childBands()){ + if (subdetailBands().contains(band->bandType())){ + if (index>band->bandIndex()) index=band->bandIndex(); + } + } + return index; +} + +QList BandDesignIntf::childrenByType(BandDesignIntf::BandsType type) +{ + QList resList; + foreach(BandDesignIntf* item,childBands()){ + if (item->bandType()==type) resList<(qgItem); + if (item) + //if (!item->canBeSplitted(height-item->pos().y())) return false; + if ((item->minHeight()>height) && (item->minHeight()>(this->height()-height))) return false; + } + } + return true; +} + +bool BandDesignIntf::isEmpty() const +{ + foreach(QGraphicsItem* qgItem,childItems()){ + BaseDesignIntf* item = dynamic_cast(qgItem); + if ((item)&&(!item->isEmpty())) return false; + } + return true; +} + +bool BandDesignIntf::isNeedRender() const +{ + return true; +} + +void BandDesignIntf::setTryToKeepTogether(bool value) +{ + m_tryToKeepTogether=value; +} + +bool BandDesignIntf::tryToKeepTogether() +{ + return m_tryToKeepTogether; +} + +void BandDesignIntf::checkEmptyTable(){ + bool isEmpty = true; + bool allItemsIsText = true; + foreach (QGraphicsItem* qgItem, childItems()) { + BaseDesignIntf* item = dynamic_cast(qgItem); + if (item && !item->isEmpty()) isEmpty = false; + if (!item) allItemsIsText = false; + } + if (isEmpty && allItemsIsText){ + foreach (QGraphicsItem* qgItem, childItems()) { + ContentItemDesignIntf* item = dynamic_cast(qgItem); + item->setHeight(0); + } + } +} + +BaseDesignIntf* BandDesignIntf::cloneUpperPart(int height, QObject *owner, QGraphicsItem *parent) +{ + int maxBottom = 0; + BandDesignIntf* upperPart = dynamic_cast(createSameTypeItem(owner,parent)); + BaseDesignIntf* upperItem; + + upperPart->initFromItem(this); + + foreach(QGraphicsItem* qgItem,childItems()){ + BaseDesignIntf* item = dynamic_cast(qgItem); + if (item){ + if (item->geometry().bottom()<=height){ + upperItem = item->cloneItem(item->itemMode(),upperPart,upperPart); + if (maxBottomgeometry().bottom()) maxBottom = upperItem->geometry().bottom(); + } + else if ((item->geometry().top()geometry().bottom()>height)){ + int sliceHeight = height-item->geometry().top(); + if (!item->isSplittable()){ + if (sliceHeight>(this->height()-sliceHeight)){ + upperItem = item->cloneItem(item->itemMode(),upperPart,upperPart); + upperItem->setHeight(height); + } else { + item->cloneEmpty(sliceHeight,upperPart,upperPart); //for table + qgItem->setPos(item->pos().x(),item->pos().y()+((height+1)-item->geometry().top())); + } + } else if (item->canBeSplitted(sliceHeight)){ + upperItem = item->cloneUpperPart(sliceHeight,upperPart,upperPart); + if (maxBottomgeometry().bottom()) maxBottom = upperItem->geometry().bottom(); + } else { + item->cloneEmpty(sliceHeight,upperPart,upperPart); //for table + qgItem->setPos(item->pos().x(),item->pos().y()+((height+1)-item->geometry().top())); + } + } + } + } + upperPart->setHeight(height); + height = maxBottom; + return upperPart; +} + +BaseDesignIntf *BandDesignIntf::cloneBottomPart(int height, QObject *owner, QGraphicsItem *parent) +{ + BandDesignIntf* bottomPart = dynamic_cast(createSameTypeItem(owner,parent)); + bottomPart->initFromItem(this); + + foreach(QGraphicsItem* qgItem,childItems()){ + BaseDesignIntf* item = dynamic_cast(qgItem); + + if (item){ + if (item->geometry().top()>height){ + BaseDesignIntf* tmpItem = item->cloneItem(item->itemMode(),bottomPart,bottomPart); + tmpItem->setPos(tmpItem->pos().x(),tmpItem->pos().y()-height); + } + else if ((item->geometry().top()geometry().bottom()>height)){ + int sliceHeight = height-item->geometry().top(); + if (item->canBeSplitted(sliceHeight)) { + BaseDesignIntf* tmpItem=item->cloneBottomPart(sliceHeight,bottomPart,bottomPart); + tmpItem->setPos(tmpItem->pos().x(),0); + if (tmpItem->pos().y()<0) tmpItem->setPos(tmpItem->pos().x(),0); + } + else if (item->isSplittable()){ + BaseDesignIntf* tmpItem = item->cloneItem(item->itemMode(),bottomPart,bottomPart); + tmpItem->setPos(tmpItem->pos().x(),0); + } else { + if ((item->geometry().bottom()-height)>height){ + BaseDesignIntf* tmpItem = item->cloneItem(item->itemMode(),bottomPart,bottomPart); + tmpItem->setPos(tmpItem->pos().x(),0); + tmpItem->setHeight((this->height()-height)); + } else { + BaseDesignIntf* tmpItem = item->cloneEmpty((this->height()-height),bottomPart,bottomPart); + if (tmpItem) + tmpItem->setPos(tmpItem->pos().x(),0); + } + } + } + } + } + + return bottomPart; +} + +void BandDesignIntf::parentObjectLoadFinished() +{ + if (!parentBandName().isEmpty()) + setParentBand(findParentBand()); +} + +void BandDesignIntf::objectLoadFinished() +{ + m_bandMarker->setHeight(height()); + BaseDesignIntf::objectLoadFinished(); +} + +void BandDesignIntf::emitBandRendered(BandDesignIntf* band) +{ + emit bandRendered(band); +} + +bool itemSortContainerLessThen(const PItemSortContainer c1, const PItemSortContainer c2) +{ + VSegment vS1(c1->m_rect),vS2(c2->m_rect); + HSegment hS1(c1->m_rect),hS2(c2->m_rect); + if (vS1.intersectValue(vS2)>hS1.intersectValue(hS2)) + return c1->m_rect.x()m_rect.x(); + else return c1->m_rect.y()m_rect.y(); +} + +bool bandIndexLessThen(const BandDesignIntf* b1, const BandDesignIntf* b2) +{ + return b1->bandIndex()bandIndex(); +} + +void BandDesignIntf::snapshotItemsLayout() +{ + m_bandItems.clear(); + foreach(BaseDesignIntf *childItem,childBaseItems()){ + m_bandItems.append(PItemSortContainer(new ItemSortContainer(childItem))); + } + qSort(m_bandItems.begin(),m_bandItems.end(),itemSortContainerLessThen); +} + +void BandDesignIntf::arrangeSubItems(RenderPass pass, ArrangeType type) +{ + bool needArrage=(type==Force); + + foreach (PItemSortContainer item, m_bandItems) { + if (item->m_item->isNeedUpdateSize(pass)){ + item->m_item->updateItemSize(pass); + needArrage=true; + } + } + + if (needArrage){ + //qSort(m_bandItems.begin(),m_bandItems.end(),itemSortContainerLessThen); + for (int i=0;im_item->collidesWithItem(m_bandItems[j]->m_item))){ + HSegment hS1(m_bandItems[j]->m_rect),hS2(m_bandItems[i]->m_rect); + VSegment vS1(m_bandItems[j]->m_rect),vS2(m_bandItems[i]->m_rect); + if (m_bandItems[i]->m_rect.bottom()m_item->geometry().bottom()){ + if (hS1.intersectValue(hS2)>vS1.intersectValue(vS2)) + m_bandItems[j]->m_item->setY(m_bandItems[i]->m_item->y()+m_bandItems[i]->m_item->height() + +m_bandItems[j]->m_rect.top()-m_bandItems[i]->m_rect.bottom()); + + } + if (m_bandItems[i]->m_rect.right()m_item->geometry().right()){ + if (vS1.intersectValue(vS2)>hS1.intersectValue(hS2)) + m_bandItems[j]->m_item->setX(m_bandItems[i]->m_item->geometry().right()+ + (m_bandItems[j]->m_rect.x()-m_bandItems[i]->m_rect.right())); + } + } + } + } + + if(needArrage||pass==FirstPass){ + int maxBottom = findMaxBottom(); + foreach(BaseDesignIntf* item,childBaseItems()){ + ItemDesignIntf* childItem=dynamic_cast(item); + if (childItem){ + if (childItem->stretchToMaxHeight()) + childItem->setHeight(maxBottom-childItem->geometry().top()); + } + } + } + +} + +qreal BandDesignIntf::findMaxBottom() +{ + qreal maxBottom=0; + foreach(QGraphicsItem* item,childItems()){ + BaseDesignIntf* subItem = dynamic_cast(item); + if(subItem) + if (subItem->geometry().bottom()>maxBottom) maxBottom=subItem->geometry().bottom(); + } + return maxBottom; +} + +qreal BandDesignIntf::findMaxHeight(){ + qreal maxHeight=0; + foreach(QGraphicsItem* item,childItems()){ + BaseDesignIntf* subItem = dynamic_cast(item); + if(subItem) + if (subItem->geometry().height()>maxHeight) maxHeight=subItem->geometry().height(); + } + return maxHeight; +} + +void BandDesignIntf::trimToMaxHeight(int maxHeight) +{ + foreach(BaseDesignIntf* item,childBaseItems()){ + if (item->height()>maxHeight) item->setHeight(maxHeight); + } +} + +QSet BandDesignIntf::groupBands() +{ + QSet result; + result< BandDesignIntf::subdetailBands() +{ + QSet result; + result<(parent())->isLoading())){ + foreach(QObject* item, parent()->children()){ + BandDesignIntf* band = dynamic_cast(item); + if(band&&(band->objectName().compare(parentBandName(),Qt::CaseInsensitive)==0)) + return band; + } + } + return 0; +} + +void BandDesignIntf::geometryChangedEvent(QRectF, QRectF ) +{ + if (((itemMode()&DesignMode) || (itemMode()&EditMode))&&parentItem()){ + QPointF sp = parentItem()->mapToScene(pos()); + if (m_bandMarker){ + m_bandMarker->setPos((sp.x()-m_bandMarker->boundingRect().width()),sp.y()); + m_bandMarker->setHeight(rect().height()); + } + } +} + +QVariant BandDesignIntf::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) +{ + if ((change==ItemPositionChange)&&((itemMode()&DesignMode)||(itemMode()&EditMode))){ + if (m_bandMarker){ + m_bandMarker->setPos((value.toPointF().x()-m_bandMarker->boundingRect().width()), + value.toPointF().y()); + } + } + if (change==ItemSelectedChange){ + if (m_bandMarker){ + m_bandMarker->update(0,0, + m_bandMarker->boundingRect().width(), + m_bandMarker->boundingRect().width()); + } + } + return BaseDesignIntf::itemChange(change,value); +} + +void BandDesignIntf::initMode(ItemMode mode) +{ + BaseDesignIntf::initMode(mode); + if ((mode==PreviewMode)||(mode==PrintMode)){ + m_bandMarker->setVisible(false); + } +} + +QColor BandDesignIntf::bandColor() const +{ + return Qt::darkBlue; +} + +void BandDesignIntf::setMarkerColor(QColor color) +{ + if (m_bandMarker) m_bandMarker->setColor(color); +} + +void BandDesignIntf::childBandDeleted(QObject *band) +{ + m_childBands.removeAt(m_childBands.indexOf(reinterpret_cast(band))); +} +bool BandDesignIntf::printIfEmpty() const +{ + return m_printIfEmpty; +} + +void BandDesignIntf::setPrintIfEmpty(bool printIfEmpty) +{ + m_printIfEmpty = printIfEmpty; +} + +bool BandDesignIntf::sliceLastRow() const +{ + return m_sliceLastRow; +} + +void BandDesignIntf::setSliceLastRow(bool sliceLastRow) +{ + m_sliceLastRow = sliceLastRow; +} + +int BandDesignIntf::maxScalePercent() const +{ + return m_maxScalePercent; +} + +void BandDesignIntf::setMaxScalePercent(int maxScalePercent) +{ + m_maxScalePercent = maxScalePercent; +} + +bool BandDesignIntf::keepFooterTogether() const +{ + return m_keepFooterTogether; +} + +void BandDesignIntf::setKeepFooterTogether(bool keepFooterTogether) +{ + m_keepFooterTogether = keepFooterTogether; +} + + +void BandDesignIntf::updateItemSize(RenderPass pass,int maxHeight) +{ + qreal spaceBorder=0; + if (keepBottomSpaceOption()) spaceBorder=height()-findMaxBottom(); + snapshotItemsLayout(); + arrangeSubItems(pass); + if (autoHeight() && height()0)&&(height()>maxHeight)){ + trimToMaxHeight(maxHeight); + setHeight(maxHeight); + } + BaseDesignIntf::updateItemSize(pass,maxHeight); +} + +QColor BandDesignIntf::selectionColor() const +{ + return Qt::yellow; +} + +DataBandDesignIntf::DataBandDesignIntf(BandDesignIntf::BandsType bandType, QString xmlTypeName, QObject *owner, QGraphicsItem *parent) + :BandDesignIntf(bandType,xmlTypeName,owner,parent) +{ +} + +} + + + diff --git a/src/lrbanddesignintf.h b/src/lrbanddesignintf.h new file mode 100644 index 0000000..86eb2ff --- /dev/null +++ b/src/lrbanddesignintf.h @@ -0,0 +1,253 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRBANDDESIGNINTF_H +#define LRBANDDESIGNINTF_H +#include "lrbasedesignintf.h" +#include + +namespace LimeReport { + +class IGropBand +{ +public: + virtual void startGroup()=0; + virtual bool isNeedToClose()=0; + virtual bool isStarted()=0; + virtual void closeGroup()=0; + virtual int index()=0; + virtual ~IGropBand(){} +}; + +class BandDesignIntf; + +class BandMarker : public QGraphicsItem{ +public: + explicit BandMarker(BandDesignIntf* band, QGraphicsItem *parent=0); + virtual QRectF boundingRect() const; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *); + void setHeight(qreal height); + void setWidth(qreal width); + void setColor(QColor color); + qreal width(){return m_rect.width();} + qreal height(){return m_rect.height();} +protected: + void mousePressEvent(QGraphicsSceneMouseEvent *event); +private: + QRectF m_rect; + QColor m_color; + BandDesignIntf* m_band; +}; + +struct ItemSortContainer; +typedef QSharedPointer< ItemSortContainer > PItemSortContainer; +class BandDesignIntf : public BaseDesignIntf +{ + Q_OBJECT + Q_PROPERTY(bool autoHeight READ autoHeight WRITE setAutoHeight ) + Q_PROPERTY(int bandIndex READ bandIndex WRITE setBandIndex DESIGNABLE false ) + Q_PROPERTY(bool keepBottomSpace READ keepBottomSpaceOption WRITE setKeepBottomSpaceOption ) + Q_PROPERTY(QString parentBand READ parentBandName WRITE setParentBandName DESIGNABLE false ) + Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) + Q_PROPERTY(bool printIfEmpty READ printIfEmpty WRITE setPrintIfEmpty) + friend class BandMarker; +public: + + enum BandsType { + PageHeader=0, + ReportHeader=1, + Data=4, + SubDetailHeader=5, + SubDetailBand=6, + SubDetailFooter=7, + GroupHeader=3, + GroupFooter=8, + ReportFooter=9, + PageFooter=10 + }; + + BandDesignIntf(BandsType bandType, const QString& xmlTypeName, QObject* owner = 0, QGraphicsItem* parent=0); + ~BandDesignIntf(); + + virtual void paint(QPainter *ppainter, const QStyleOptionGraphicsItem *option, QWidget *widget); + virtual BandsType bandType() const; + virtual QString bandTitle() const; + virtual QIcon bandIcon() const; + virtual bool isUnique() const; + virtual void updateItemSize(RenderPass pass=FirstPass, int maxHeight=0); + + virtual QColor selectionColor() const; + int bandIndex() const; + void setBandIndex(int value); + + void setBandType(BandsType value){m_bandType=value;} + + QString datasourceName(); + void setDataSourceName(const QString& datasourceName); + + void setKeepBottomSpaceOption(bool value){m_keepBottomSpace=value;} + bool keepBottomSpaceOption() const {return m_keepBottomSpace;} + + void addChildBand(BandDesignIntf* band); + bool hasChildren(){return !m_childBands.isEmpty();} + void removeChildBand(BandDesignIntf* band); + void setParentBand(BandDesignIntf* band); + + void setParentBandName(const QString& parentBandName); + QString parentBandName(){return m_parentBandName;} + + bool isConnectedToBand(BandDesignIntf::BandsType bandType) const; + + int maxChildIndex(QSet bandTypes) const; + int groupFooterIndex(int groupHeaderIndex); + int groupHeaderIndex(); + + BandDesignIntf* parentBand() const {return m_parentBand;} + + QList childBands() const{return m_childBands;} + QList childrenByType(BandDesignIntf::BandsType type); + + virtual bool canBeSplitted(int height) const; + virtual bool isEmpty() const; + virtual bool isNeedRender() const; + virtual bool isFooter() const {return false;} + virtual bool isData() const {return false;} + + void setTryToKeepTogether(bool value); + bool tryToKeepTogether(); + + BaseDesignIntf* cloneUpperPart(int height, QObject* owner=0, QGraphicsItem* parent=0); + BaseDesignIntf* cloneBottomPart(int height, QObject *owner=0, QGraphicsItem *parent=0); + void parentObjectLoadFinished(); + void objectLoadFinished(); + void emitBandRendered(BandDesignIntf *band); + + bool isSplittable() const {return m_splitable;} + void setSplittable(bool value){m_splitable=value;} + + bool keepFooterTogether() const; + void setKeepFooterTogether(bool keepFooterTogether); + + int maxScalePercent() const; + void setMaxScalePercent(int maxScalePercent); + + bool sliceLastRow() const; + void setSliceLastRow(bool sliceLastRow); + + bool printIfEmpty() const; + void setPrintIfEmpty(bool printIfEmpty); + +signals: + void bandRendered(BandDesignIntf* band); +protected: + void snapshotItemsLayout(); + void arrangeSubItems(RenderPass pass, ArrangeType type = AsNeeded); + qreal findMaxBottom(); + qreal findMaxHeight(); + void trimToMaxHeight(int maxHeight); + + void setAutoHeight(bool value){m_autoHeight=value;} + bool autoHeight(){return m_autoHeight;} + + void setBandTypeText(const QString& value){m_bandTypeText=value;} + QString bandTypeText(){return m_bandTypeText;} + virtual void moveDown(){} + virtual void moveUp(){} + QSet groupBands(); + QSet subdetailBands(); + BandDesignIntf *findParentBand(); + virtual void geometryChangedEvent(QRectF, QRectF); + virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + virtual void initMode(ItemMode mode); + virtual QColor bandColor() const; + void setMarkerColor(QColor color); + void checkEmptyTable(); +private slots: + void childBandDeleted(QObject* band); +private: + QString m_bandTypeText; + BandsType m_bandType; + int m_bandIndex; + QString m_dataSourceName; + bool m_autoHeight; + bool m_keepBottomSpace; + BandDesignIntf* m_parentBand; + QString m_parentBandName; + QList m_childBands; + QVector m_bandItems; + BandMarker* m_bandMarker; + bool m_tryToKeepTogether; + bool m_splitable; + bool m_keepFooterTogether; + int m_maxScalePercent; + bool m_sliceLastRow; + bool m_printIfEmpty; +}; + +class DataBandDesignIntf : public BandDesignIntf{ + Q_OBJECT + Q_PROPERTY(QString datasource READ datasourceName WRITE setDataSourceName ) +public: + DataBandDesignIntf(BandsType bandType, QString xmlTypeName, QObject* owner = 0, QGraphicsItem* parent=0); +}; + +class Segment{ +public: + Segment(qreal segmentStart,qreal segmentEnd):m_begin(segmentStart),m_end(segmentEnd){} + bool intersect(Segment value); + qreal intersectValue(Segment value); +private: + qreal m_begin; + qreal m_end; +}; + +class VSegment : public Segment{ +public: + VSegment(QRectF rect):Segment(rect.top(),rect.bottom()){} +}; + +struct HSegment :public Segment{ +public: + HSegment(QRectF rect):Segment(rect.left(),rect.right()){} +}; + +struct ItemSortContainer { + QRectF m_rect; + BaseDesignIntf * m_item; + ItemSortContainer(BaseDesignIntf *item){ + m_item=item; + m_rect=item->geometry(); + } +}; + +bool itemSortContainerLessThen(const PItemSortContainer c1, const PItemSortContainer c2); +bool bandIndexLessThen(const BandDesignIntf* b1, const BandDesignIntf* b2); + +} +#endif // LRBANDDESIGNINTF_H diff --git a/src/lrbandsmanager.cpp b/src/lrbandsmanager.cpp new file mode 100644 index 0000000..6a15969 --- /dev/null +++ b/src/lrbandsmanager.cpp @@ -0,0 +1,93 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrbandsmanager.h" +#include "lrglobal.h" + +#include "lrpageheader.h" +#include "lrpagefooter.h" +#include "lrreportheader.h" +#include "lrreportfooter.h" +#include "lrdataband.h" +#include "lrsubdetailband.h" +#include "lrgroupbands.h" + +namespace LimeReport{ +BandsManager::BandsManager(){} + +QStringList BandsManager::bandNames() +{ + QStringList bandsList; + bandsList<(LimeReport::DesignElementsFactory::instance().objectCreator(identity)(owner,parent)); +} + +BandDesignIntf *BandsManager::createBand(BandDesignIntf::BandsType bandType, QObject *owner, BaseDesignIntf *parent) +{ + switch(bandType){ + case BandDesignIntf::ReportHeader: + return new ReportHeader(owner,parent); + case BandDesignIntf::ReportFooter: + return new ReportFooter(owner,parent); + case BandDesignIntf::PageHeader: + return new PageHeader(owner,parent); + case BandDesignIntf::PageFooter: + return new PageFooter(owner,parent); + case BandDesignIntf::Data: + return new DataBand(owner,parent); + case BandDesignIntf::SubDetailBand: + return new SubDetailBand(owner,parent); + case BandDesignIntf::SubDetailHeader: + return new SubDetailHeaderBand(owner,parent); + case BandDesignIntf::SubDetailFooter: + return new SubDetailFooterBand(owner,parent); + case BandDesignIntf::GroupHeader: + return new GroupBandHeader(owner, parent); + case BandDesignIntf::GroupFooter: + return new GroupBandFooter(owner, parent); + } + + return 0; +} + +} diff --git a/src/lrbandsmanager.h b/src/lrbandsmanager.h new file mode 100644 index 0000000..0a850c7 --- /dev/null +++ b/src/lrbandsmanager.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRBANDSMANAGER_H +#define LRBANDSMANAGER_H + +#include +#include +#include +#include "lrdesignelementsfactory.h" +#include "lrbanddesignintf.h" +#include "lrbasedesignintf.h" + +namespace LimeReport{ +class BandsManager +{ +public: + BandsManager(); + QStringList bandNames(); + BandDesignIntf * createBand(const QString& type, QObject* owner, LimeReport::BaseDesignIntf* parent ); + BandDesignIntf * createBand(BandDesignIntf::BandsType bandType, QObject* owner, LimeReport::BaseDesignIntf* parent ); +}; +} +#endif // LRBANDSMANAGER_H diff --git a/src/lrbasedesignintf.cpp b/src/lrbasedesignintf.cpp new file mode 100644 index 0000000..66b72d0 --- /dev/null +++ b/src/lrbasedesignintf.cpp @@ -0,0 +1,1100 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include +#include "lrbasedesignintf.h" +#include "lrglobal.h" +#include "lrpagedesignintf.h" +#include "lrreportdesignwidget.h" +#include "qgraphicsitem.h" +#include "lrdesignelementsfactory.h" + +#include "lrhorizontallayout.h" + +#include + +#include +#include +#include +#include +#include + +namespace LimeReport +{ + +BaseDesignIntf::BaseDesignIntf(const QString &storageTypeName, QObject *owner, QGraphicsItem *parent) : + QObject(owner), QGraphicsItem(parent), + m_resizeHandleSize(Consts::RESIZE_HANDLE_SIZE), + m_selectionPenSize(Consts::SELECTION_PEN_SIZE), + m_posibleResizeDirectionFlags(ResizeTop | ResizeBottom | ResizeLeft | ResizeRight), + m_posibleMoveDirectionFlags(All), + m_resizeDirectionFlags(0), + m_width(200), + m_height(50), + m_fontColor(Qt::black), + m_mmFactor(mmFACTOR), + m_fixedPos(false), + m_BGMode(OpaqueMode), + m_opacity(100), + m_borderLinesFlags(0), + m_hintFrame(0), + m_storageTypeName(storageTypeName), + m_itemMode(DesignMode), + m_objectState(ObjectCreated), + m_selectionMarker(0), + m_backgroundBrush(Solid), + m_backgroundBrushcolor(Qt::white), + m_margin(4) +{ + setGeometry(QRectF(0, 0, m_width, m_height)); + if (BaseDesignIntf *item = dynamic_cast(parent)) { + m_font = item->font(); + } else{ + m_font = QFont("Arial",10); + } + initFlags(); + m_selectionMarker = new SelectionMarker(this); + m_selectionMarker->setColor(Consts::SELECTION_COLOR); + m_selectionMarker->setVisible(false); + //connect(this,SIGNAL(objectNameChanged(QString)),this,SLOT(slotObjectNameChanged(QString))); +} + +QRectF BaseDesignIntf::boundingRect() const +{ + if (m_boundingRect.isNull()) { + qreal halfpw = pen().widthF() / 2; + halfpw += 2; + m_boundingRect = rect(); + m_boundingRect.adjust(-halfpw, -halfpw, halfpw, halfpw); + }; + return m_boundingRect; +} + +BaseDesignIntf::~BaseDesignIntf(void) {delete m_selectionMarker;} + +void BaseDesignIntf::setParentReportItem(const QString &value) +{ + if (page() && !value.isEmpty()) { + BaseDesignIntf *p = page()->reportItemByName(value); + if (p) { + setParentItem(p); + setParent(p); + } + } +} + +QString BaseDesignIntf::parentReportItem() +{ + BaseDesignIntf *parent = dynamic_cast(parentItem()); + if (parent) return parent->objectName(); + else return ""; +} + +void BaseDesignIntf::setBackgroundBrushMode(BaseDesignIntf::BrushMode value) +{ + if ( value != m_backgroundBrush ){ + m_backgroundBrush=value; + if (!isLoading()) update(); + } +} + +void BaseDesignIntf::setBackgroundColor(QColor value) +{ + if (value != m_backgroundBrushcolor){ + QColor oldValue = m_backgroundBrushcolor; + m_backgroundBrushcolor=value; + if (!isLoading()) update(); + notify("backgroundColor",oldValue,m_backgroundBrushcolor); + } +} + +QPen BaseDesignIntf::pen() const +{ + return m_pen; +} + +void BaseDesignIntf::setPen(QPen &pen) +{ + m_pen = pen; + update(); +} + +QFont BaseDesignIntf::font() const +{ + return m_font; +} + +void BaseDesignIntf::setFont(QFont &font) +{ + m_font = font; + update(); +} + +qreal BaseDesignIntf::width() const +{ + return rect().width(); +} + +void BaseDesignIntf::setWidth(qreal width) +{ + setGeometry(QRectF(rect().x(), rect().y(), width, rect().height())); +} + +qreal BaseDesignIntf::height() const +{ + return rect().height(); +} + +QRectF BaseDesignIntf::geometry() const +{ + return QRectF(pos().x(), pos().y(), width(), height()); +} + +void BaseDesignIntf::setHeight(qreal height) +{ + setGeometry(QRectF(rect().x(), rect().y(), rect().width(), height)); +} + +QFont BaseDesignIntf::transformToSceneFont(const QFont& value) const +{ + QFont f = value; + f.setPixelSize(f.pointSize()*fontFACTOR); + return f; +} + +void BaseDesignIntf::setupPainter(QPainter *painter) const +{ + if (!painter) { + return; + } + painter->setFont(m_font); + painter->setPen(m_fontColor); +} + +BaseDesignIntf::BGMode BaseDesignIntf::backgroundMode() const +{ + return m_BGMode; +} +void BaseDesignIntf::setBackgroundMode(BGMode bgMode) +{ + m_BGMode = bgMode; + update(boundingRect()); +} + +int BaseDesignIntf::opacity() const +{ + return m_opacity; +} + +void BaseDesignIntf::setOpacity(int opacity) +{ + if (m_opacity!=opacity){ + if (opacity < 0) { + m_opacity = 0; + } + else if (opacity > 100) { + m_opacity = 100; + } + else { + m_opacity = opacity; + } + update(); + } +} + +void BaseDesignIntf::setSize(QSizeF size) +{ + setWidth(size.width()); + setHeight(size.height()); +} + +QSizeF BaseDesignIntf::size() const +{ + return QSizeF(width(), height()); +} + +QSizeF BaseDesignIntf::sizeMM() const +{ + return QSizeF(width() / m_mmFactor, height() / m_mmFactor); +} + +qreal BaseDesignIntf::widthMM() const +{ + return width() / m_mmFactor; +} + +qreal BaseDesignIntf::heightMM() const +{ + return height() / m_mmFactor; +} + +void BaseDesignIntf::setMMFactor(qreal mmFactor) +{ + m_mmFactor = mmFactor; +} + +qreal BaseDesignIntf::mmFactor() const +{ + return m_mmFactor; +} + +QPointF BaseDesignIntf::posMM() const +{ + return QPointF(pos().x() / m_mmFactor, pos().y() / m_mmFactor); +} + +QRectF BaseDesignIntf::rect() const +{ + return m_rect; +} + +void BaseDesignIntf::setFixedPos(bool fixedPos) +{ + m_fixedPos = fixedPos; +} + +void BaseDesignIntf::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + m_resizeDirectionFlags = resizeDirectionFlags(event->pos()); + m_startScenePos = event->scenePos(); + m_startPos = pos(); + m_oldGeometry = geometry(); + QGraphicsItem::mousePressEvent(event); + QApplication::processEvents(); + emit(itemSelected(this)); + } + else QGraphicsItem::mouseMoveEvent(event); +} + +void BaseDesignIntf::paint(QPainter *ppainter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + setupPainter(ppainter); + + drawBorder(ppainter, rect()); + if (isSelected()) {drawSelection(ppainter, rect());} + drawResizeZone(ppainter); +} + +void BaseDesignIntf::prepareRect(QPainter *ppainter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) +{ + ppainter->save(); + if (isSelected() && (opacity() == 100) && (m_BGMode!=TransparentMode)) { + ppainter->fillRect(rect(), QBrush(QColor(m_backgroundBrushcolor))); + } + else { + if (m_BGMode == OpaqueMode) { + ppainter->setOpacity(qreal(m_opacity) / 100); + ppainter->fillRect(rect(), QBrush(m_backgroundBrushcolor)); + } + } + ppainter->restore(); +} + +void BaseDesignIntf::hoverMoveEvent(QGraphicsSceneHoverEvent *event) +{ + if (page()) { + if (!page()->isItemInsertMode()) { + if (m_resizeDirectionFlags != resizeDirectionFlags(event->pos())) { + m_resizeDirectionFlags = resizeDirectionFlags(event->pos()); + QVectoroldResizeAreas(m_resizeAreas); + initResizeZones(); + invalidateRects(oldResizeAreas); + invalidateRects(m_resizeAreas); + } + } + } +} + +void BaseDesignIntf::invalidateRects(QVector rects) +{ + foreach(QRectF * rect, rects) + scene()->update(mapToScene(*rect).boundingRect()); +} + +void BaseDesignIntf::hoverLeaveEvent(QGraphicsSceneHoverEvent *) +{ + setCursor(QCursor(Qt::ArrowCursor)); + m_resizeDirectionFlags = 0; + scene()->update(sceneBoundingRect()); + m_resizeAreas.clear(); +} + + +void BaseDesignIntf::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + + if (m_resizeDirectionFlags & ResizeLeft) { + if ((event->scenePos().x()) <= (mapToScene(0, 0).x() + (width() - Consts::MINIMUM_ITEM_WIDTH)) && + (width() + (event->lastScenePos().x() - event->scenePos().x()) > Consts::MINIMUM_ITEM_WIDTH) + ) { + qreal posRightConner = mapToScene(0, 0).x() + width(); + setItemPos(mapToParent(mapFromScene(div(event->scenePos().x(), 2).quot * 2, y())).x(), y()); + setWidth(posRightConner - div(event->scenePos().x(), 2).quot * 2); + } + } + + if (m_resizeDirectionFlags & ResizeRight) { + if ((event->scenePos().x() >= (mapToScene(0, 0).x() + Consts::MINIMUM_ITEM_WIDTH)) || + (event->scenePos().x() >= (mapToScene(0, 0).x() + width()))) { + setWidth(div(int(event->scenePos().x()) - int(mapToScene(0, 0).x()), 2).quot * 2); + } + } + + if (m_resizeDirectionFlags & ResizeBottom) { + if ((event->scenePos().y() > (mapToScene(0, 0).y() + height())) || + (event->scenePos().y() > (mapToScene(0, 0).y() + Consts::MINIMUM_ITEM_HEIGHT)) + ) { + setHeight(div(int(event->scenePos().y()) - int(mapToScene(0, 0).y()), 2).quot * 2); + } + } + + if (m_resizeDirectionFlags & ResizeTop) { + + if ((event->scenePos().y()) <= (mapToScene(0, 0).y() + (height() - Consts::MINIMUM_ITEM_HEIGHT)) && + (height() + (event->lastScenePos().y() - event->scenePos().y()) > Consts::MINIMUM_ITEM_HEIGHT) + ) { + qreal posBottomConner = int(mapToScene(0, 0).y()) + int(height()); + setItemPos(x(), div(mapToParent(event->pos()).y(), 2).quot * 2); + setHeight(posBottomConner - div(event->scenePos().y(), 2).quot * 2); + } + } + + if ((m_resizeDirectionFlags == Fixed) && !m_fixedPos) { + + QPointF tmpPos = pos(); + QPointF delta; + switch (posibleMoveDirectionFlags()) { + case LeftRight: { + delta = QPoint(div(m_startScenePos.x() - event->scenePos().x(), 2).quot * 2, 0); + break; + } + case TopBotom: { + delta = QPoint(0, div(m_startScenePos.y() - event->scenePos().y(), 2).quot * 2); + break; + } + case All: { + delta = QPoint(div(m_startScenePos.x() - event->scenePos().x(), 2).quot * 2, + div(m_startScenePos.y() - event->scenePos().y(), 2).quot * 2); + break; + } + }; + + setItemPos(m_startPos - delta); + moveSelectedItems(tmpPos - pos()); + } +} + +int BaseDesignIntf::posibleResizeDirectionFlags() const +{ + return m_posibleResizeDirectionFlags; +} + +int BaseDesignIntf::resizeHandleSize() const +{ + return m_resizeHandleSize; +} + +int BaseDesignIntf::resizeDirectionFlags(QPointF position) +{ + int flags = Fixed; + + if (posibleResizeDirectionFlags()&ResizeTop && m_topRect.contains(position)) { + flags |= ResizeTop; + } + + if (posibleResizeDirectionFlags()&ResizeLeft && m_leftRect.contains(position)) { + flags |= ResizeLeft; + } + + if (posibleResizeDirectionFlags()&ResizeBottom && m_bottomRect.contains(position)) { + flags |= ResizeBottom; + } + + if (posibleResizeDirectionFlags()&ResizeRight && m_rightRect.contains(position)) { + flags |= ResizeRight; + } + +// if (posibleResizeDirectionFlags()&FixedSize) { +// flags |= FixedSize; +// } + + return flags; +} + +Qt::CursorShape BaseDesignIntf::getPosibleCursor(int cursorFlags) +{ + + if ((cursorFlags == Fixed) || (scene()->selectedItems().count() > 1)) return Qt::ArrowCursor; + + if (((cursorFlags & ResizeRight) && (cursorFlags & ResizeTop)) || + ((cursorFlags & ResizeLeft) && (cursorFlags & ResizeBottom))) { + return Qt::SizeBDiagCursor; + } + if (((cursorFlags & ResizeLeft) && (cursorFlags & ResizeTop)) || + ((cursorFlags & ResizeRight) && (cursorFlags & ResizeBottom))) { + return Qt::SizeFDiagCursor; + } + if ((cursorFlags & ResizeLeft) || (cursorFlags & ResizeRight)) { return Qt::SizeHorCursor; } + if ((cursorFlags & ResizeBottom) || (cursorFlags & ResizeTop)) { return Qt::SizeVerCursor; } + + return Qt::ArrowCursor; +} + +void BaseDesignIntf::setZValueProperty(qreal value) +{ + if (zValue()!=value){ + qreal oldValue = zValue(); + setZValue(value); + notify("zOrder",oldValue,value); + } +} + +//void BaseDesignIntf::slotObjectNameChanged(const QString &newName) +//{ +// if (!isLoading() && page() && this->itemMode()==LimeReport::DesignMode){ +// QList list = page()->reportItemsByName(newName); +// if (list.size()>1){ +// setObjectName(page()->genObjectName(*this)); +// notify("objectName",newName,objectName()); +// } + +// } +//} + +QString BaseDesignIntf::itemTypeName() const +{ + return m_itemTypeName; +} + +void BaseDesignIntf::setItemTypeName(const QString &itemTypeName) +{ + m_itemTypeName = itemTypeName; +} + +void BaseDesignIntf::emitObjectNamePropertyChanged(const QString &oldName, const QString &newName) +{ + emit propertyObjectNameChanged(oldName,newName); +} + + +void BaseDesignIntf::moveRight() +{ + if (!m_fixedPos) setItemPos(pos().x() + 2, pos().y()); +} + +void BaseDesignIntf::moveLeft() +{ + if (!m_fixedPos) setItemPos(pos().x() - 2, pos().y()); +} + +void BaseDesignIntf::moveDown() +{ + if (!m_fixedPos) setItemPos(pos().x(), pos().y() + 2); +} + +void BaseDesignIntf::moveUp() +{ + if (!m_fixedPos) setItemPos(pos().x(), pos().y() - 2); +} + +void BaseDesignIntf::sizeRight() +{ + if ((m_posibleResizeDirectionFlags & ResizeLeft) || + (m_posibleResizeDirectionFlags & ResizeRight)) { + setWidth(width() + 2); + } +} + +void BaseDesignIntf::sizeLeft() +{ + if ((m_posibleResizeDirectionFlags & ResizeLeft) || + (m_posibleResizeDirectionFlags & ResizeRight)) { + setWidth(width() - 2); + } +} + +void BaseDesignIntf::sizeUp() +{ + if ((m_posibleResizeDirectionFlags & ResizeTop) || + (m_posibleResizeDirectionFlags & ResizeBottom)) { + setHeight(height() - 2); + } +} + +void BaseDesignIntf::sizeDown() +{ + if ((m_posibleResizeDirectionFlags & ResizeTop) || + (m_posibleResizeDirectionFlags & ResizeBottom)) { + setHeight(height() + 2); + } +} + +void BaseDesignIntf::setBorderLinesFlags(BorderLines flags) +{ + if (m_borderLinesFlags!=flags){ + BorderLines oldValue = m_borderLinesFlags; + m_borderLinesFlags = flags; + if (!isLoading()) { + update(rect()); + notify("borders",QVariant(oldValue),QVariant(flags)); + } + } +} + +BaseDesignIntf::BorderLines BaseDesignIntf::borderLines() const +{ + return m_borderLinesFlags; +} + +void BaseDesignIntf::drawTopLine(QPainter *painter, QRectF rect) const +{ + painter->setPen(borderPen(TopLine)); + painter->drawLine(rect.x(), rect.y(), rect.width(), rect.y()); +} + +void BaseDesignIntf::drawBootomLine(QPainter *painter, QRectF rect) const +{ + painter->setPen(borderPen(BottomLine)); + painter->drawLine(rect.x(), rect.height(), rect.width(), rect.height()); +} + +void BaseDesignIntf::drawRightLine(QPainter *painter, QRectF rect) const +{ + painter->setPen(borderPen(RightLine)); + painter->drawLine(rect.width(), rect.y(), rect.width(), rect.height()); +} + +void BaseDesignIntf::drawLeftLine(QPainter *painter, QRectF rect) const +{ + painter->setPen(borderPen(LeftLine)); + painter->drawLine(rect.x(), rect.y(), rect.x(), rect.height()); +} + +void BaseDesignIntf::drawDesignModeBorder(QPainter *painter, QRectF rect) const +{ + drawTopLine(painter, rect); + drawBootomLine(painter, rect); + drawLeftLine(painter, rect); + drawRightLine(painter, rect); +} + +void BaseDesignIntf::drawRenderModeBorder(QPainter *painter, QRectF rect) const +{ + + if (m_borderLinesFlags & RightLine) drawRightLine(painter, rect); + if (m_borderLinesFlags & LeftLine) drawLeftLine(painter, rect); + if (m_borderLinesFlags & TopLine ) drawTopLine(painter, rect); + if (m_borderLinesFlags & BottomLine) drawBootomLine(painter, rect); +} + +void BaseDesignIntf::drawBorder(QPainter *painter, QRectF rect) const +{ + painter->save(); + if (itemMode() & DesignMode) { + drawDesignModeBorder(painter, rect); + } + else drawRenderModeBorder(painter, rect); + painter->restore(); +} + +void BaseDesignIntf::setGeometry(QRectF rect) +{ + if (m_rect == rect) return; + m_oldGeometry = m_rect; + if (!isLoading()) + prepareGeometryChange(); + m_rect = rect; + m_topRect = QRectF(0, 0, width(), resizeHandleSize()); + m_bottomRect = QRectF(0, height() - resizeHandleSize(), width(), resizeHandleSize()); + m_leftRect = QRectF(0, 0, resizeHandleSize(), height()); + m_rightRect = QRectF(width() - resizeHandleSize(), 0, resizeHandleSize(), height()); + m_boundingRect = QRectF(); + updateSelectionMarker(); + if (!isLoading()){ + geometryChangedEvent(geometry(), m_oldGeometry); + emit geometryChanged(this, geometry(), m_oldGeometry); + } +} + +void BaseDesignIntf::geometryChangedEvent(QRectF newRect, QRectF oldRect) +{ + Q_UNUSED(oldRect); + Q_UNUSED(newRect); +} + +void BaseDesignIntf::beforeDelete() +{ + +} + +void BaseDesignIntf::setGeometryProperty(QRectF rect) +{ + if (rect!=geometry()){ + QRectF oldValue = geometry(); + if ((rect.x() != geometry().x()) || (rect.y() != geometry().y())) + setPos(rect.x(), rect.y()); + if (rect.width() != geometry().width()) + setWidth(rect.width()); + if (rect.height() != geometry().height()) + setHeight(rect.height()); + + if (!isLoading()) notify("geometry",oldValue,rect); + } + +} + +PageDesignIntf *BaseDesignIntf::page() +{ + return dynamic_cast(scene()); +} + +void BaseDesignIntf::setPosibleResizeDirectionFlags(int directionsFlags) +{ + m_posibleResizeDirectionFlags = directionsFlags; +} + +QPen BaseDesignIntf::borderPen(BorderSide side/*, bool selected*/) const +{ + QPen pen; + if (m_borderLinesFlags & side) {pen.setColor(Qt::black); pen.setStyle(Qt::SolidLine);} + else {pen.setColor(Qt::darkGray); pen.setStyle(Qt::SolidLine);} + return pen; +} + +QColor BaseDesignIntf::selectionColor() const +{ + return Consts::SELECTION_COLOR; +} + +void BaseDesignIntf::initFlags() +{ + if ((itemMode()&DesignMode) || (itemMode()&EditMode)) { + setFlag(QGraphicsItem::ItemIsSelectable); + setFlag(QGraphicsItem::ItemSendsGeometryChanges); + setAcceptHoverEvents(true); + } + else { + setFlag(QGraphicsItem::ItemIsSelectable, false); + setAcceptHoverEvents(false); + } + +} + +void BaseDesignIntf::initMode(ItemMode mode) +{ + Q_UNUSED(mode); +} + +QVariant BaseDesignIntf::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) +{ + if (change == QGraphicsItem::ItemPositionHasChanged) { + updateSelectionMarker(); + } + if (change == QGraphicsItem::ItemSelectedChange) { + updateSelectionMarker(); + m_selectionMarker->setVisible(value.toBool()); + } + return QGraphicsItem::itemChange(change, value); +} + +void BaseDesignIntf::childAddedEvent(BaseDesignIntf *child) +{ + Q_UNUSED(child) +} + +QPainterPath BaseDesignIntf::shape() const +{ + QPainterPath path; + path.addRect(this->boundingRect()); + return path; +} + +void BaseDesignIntf::drawSelection(QPainter *painter, QRectF /*rect*/) const +{ + painter->save(); + // painter->setPen(QPen(Qt::red,m_selectionPenSize)); + // painter->drawLine(QPointF(m_resizeHandleSize,0),QPointF(0,0)); + // painter->drawLine(QPointF(0,m_resizeHandleSize),QPointF(0,0)); + // painter->drawLine(rect.right()-m_resizeHandleSize,0,rect.right(),0); + // painter->drawLine(rect.right(),m_resizeHandleSize,rect.right(),0); + // painter->drawLine(0,rect.bottom(),0,rect.bottom()-10); + // painter->drawLine(0,rect.bottom(),m_resizeHandleSize,rect.bottom()); + // painter->drawLine(rect.right()-m_resizeHandleSize,rect.bottom(),rect.right(),rect.bottom()); + // painter->drawLine(rect.right(),rect.bottom()-m_resizeHandleSize,rect.right(),rect.bottom()); + // painter->setOpacity(Consts::SELECTION_COLOR_OPACITY); + // painter->fillRect(rect,selectionColor()); + painter->restore(); +} + +void BaseDesignIntf::moveSelectedItems(QPointF delta) +{ + QList selectedItems; + selectedItems = scene()->selectedItems(); + BaseDesignIntf *selectedItem; + foreach(QGraphicsItem * item, selectedItems) { + if (item != this) { + selectedItem = dynamic_cast(item); + if (selectedItem) { + if (!selectedItem->m_fixedPos) + selectedItem->setItemPos(selectedItem->pos() - delta); + } + } + } +} + +void BaseDesignIntf::setItemPos(qreal x, qreal y) +{ + setItemPos(QPointF(x, y)); +} + +void BaseDesignIntf::setItemMode(ItemMode mode) +{ + m_itemMode = mode; + foreach(QGraphicsItem * item, childItems()) { + BaseDesignIntf *ri = dynamic_cast(item); + if (ri) ri->setItemMode(mode); + } + initMode(mode); + initFlags(); +} +void BaseDesignIntf::setItemPos(const QPointF &newPos) +{ + QPointF oldPos = pos(); + QGraphicsItem::setPos(newPos); + emit posChanged(this, newPos, oldPos); +} + +void BaseDesignIntf::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + QGraphicsItem::mouseReleaseEvent(event); + QRectF newGeometry = geometry(); + if (newGeometry != m_oldGeometry) { + geometryChangedEvent(newGeometry, m_oldGeometry); + updateSelectionMarker(); + emit(geometryChanged(this, newGeometry, m_oldGeometry)); + } +} + +void BaseDesignIntf::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) +{ + if (event->button() == Qt::LeftButton && + ((itemMode()&EditMode)||(itemMode()&DesignMode)) + ) { + QWidget *editor = defaultEditor(); + if (editor) { + +#if defined(WIN32) || defined(WIN64) + editor->setAttribute(Qt::WA_DeleteOnClose); + editor->setWindowFlags(Qt::Dialog); + editor->setWindowModality(Qt::ApplicationModal); + editor->show(); +#else + QDialog* dialog = new QDialog(QApplication::activeWindow()); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->setWindowModality(Qt::WindowModal); + dialog->setLayout(new QVBoxLayout()); + dialog->resize(editor->size()); + dialog->layout()->setContentsMargins(2,2,2,2); + dialog->layout()->addWidget(editor); + connect(editor,SIGNAL(destroyed()),dialog,SLOT(close())); + dialog->exec(); +#endif + } + } + QGraphicsItem::mouseDoubleClickEvent(event); +} + +int BaseDesignIntf::posibleMoveDirectionFlags() const +{ + return m_posibleMoveDirectionFlags; +} + +void BaseDesignIntf::setPosibleMoveFlags(int directionsFlags) +{ + m_posibleMoveDirectionFlags = directionsFlags; +} + +void BaseDesignIntf::setMarginSize(int value) +{ + if (m_margin!=value){ + int oldValue = m_margin; + m_margin=value; + if (!isLoading()){ + update(rect()); + notify("margin", oldValue, value); + } + } +} + +void BaseDesignIntf::updateSelectionMarker() +{ + if (m_selectionMarker && (itemMode() & DesignMode || itemMode() & EditMode)) { + if ((!m_selectionMarker->scene()) && scene()) scene()->addItem(m_selectionMarker); + if (parentItem()) { + m_selectionMarker->setRect(rect()); + m_selectionMarker->setPos(0,0/*parentItem()->mapToScene(pos())*/); + } + } +} + +void BaseDesignIntf::drawResizeZone(QPainter *painter) +{ + + if (m_resizeAreas.count() > 0) { + painter->save(); + painter->setPen(QPen(Consts::RESIZE_ZONE_COLOR)); + (isSelected()) ? painter->setOpacity(Consts::SELECTED_RESIZE_ZONE_OPACITY) : painter->setOpacity(Consts::RESIZE_ZONE_OPACITY); + painter->setBrush(QBrush(Qt::green, Qt::SolidPattern)); + foreach(QRectF * resizeArea, m_resizeAreas) painter->drawRect(*resizeArea); + painter->restore(); + } + +} + +void BaseDesignIntf::initResizeZones() +{ + m_resizeAreas.clear(); + if (m_resizeDirectionFlags & ResizeBottom) m_resizeAreas.append(&m_bottomRect); + if (m_resizeDirectionFlags & ResizeTop) m_resizeAreas.append(&m_topRect); + if (m_resizeDirectionFlags & ResizeLeft) m_resizeAreas.append(&m_leftRect); + if (m_resizeDirectionFlags & ResizeRight) m_resizeAreas.append(&m_rightRect); +} + +void BaseDesignIntf::invalidateRect(const QRectF &rect) +{ + if (scene()) + scene()->update(mapToScene(rect).boundingRect()); +} + +ReportEnginePrivate *BaseDesignIntf::reportEditor() +{ + PageDesignIntf *page = dynamic_cast(scene()); + if (page) return page->reportEditor(); + else return 0; +} + +void BaseDesignIntf::updateItemSize(RenderPass pass, int maxHeight) +{ + Q_UNUSED(maxHeight); + m_currentPass = pass; +} + +bool BaseDesignIntf::isNeedUpdateSize(RenderPass /*pass*/) const +{return false;} + +void BaseDesignIntf::drawPinArea(QPainter *painter) const +{ + painter->drawRect(QRect(0, 0, 16, 16)); +} + +QObject *BaseDesignIntf::createElement(const QString& /*collectionName*/, const QString &elementType) +{ + BaseDesignIntf* obj = 0; + try{ + obj = LimeReport::DesignElementsFactory::instance().objectCreator(elementType)(this, this); + connect(obj,SIGNAL(propertyChanged(QString,QVariant,QVariant)),page(),SLOT(slotItemPropertyChanged(QString,QVariant,QVariant))); + } catch (ReportError error){ + qDebug()<(obj); + if (item) { + page()->registerItem(item); + } + } + } + } + emit loadCollectionFinished(collectionName); +} + +BaseDesignIntf *BaseDesignIntf::cloneItem(ItemMode mode, QObject *owner, QGraphicsItem *parent) +{ + BaseDesignIntf *clone = cloneItemWOChild(mode, owner, parent); +#ifdef HAVE_QT5 + foreach(QObject * child, children()) { +#else + foreach(QObject * child, QObject::children()) { +#endif + BaseDesignIntf *childItem = dynamic_cast(child); + if (childItem) {clone->childAddedEvent(childItem->cloneItem(mode, clone, clone));} + } + return clone; +} + +BaseDesignIntf *BaseDesignIntf::cloneItemWOChild(ItemMode mode, QObject *owner, QGraphicsItem *parent) +{ + BaseDesignIntf *clone = createSameTypeItem(owner, parent); + clone->setObjectName(this->objectName()); + clone->setItemMode(mode); + clone->objectLoadStarted(); + for (int i = 0; i < clone->metaObject()->propertyCount(); i++) { + if (clone->metaObject()->property(i).isWritable()) + clone->setProperty(clone->metaObject()->property(i).name(), property(clone->metaObject()->property(i).name())); + } + clone->objectLoadFinished(); + return clone; +} + +void BaseDesignIntf::initFromItem(BaseDesignIntf *source) +{ + objectLoadStarted(); + for (int i = 0; i < metaObject()->propertyCount(); i++) { + if (strcmp(metaObject()->property(i).name(),"objectName")!=0) + if (source->property(metaObject()->property(i).name()).isValid()) { + if (metaObject()->property(i).isWritable()) + setProperty(metaObject()->property(i).name(), source->property(metaObject()->property(i).name())); + } + } + objectLoadFinished(); +} + +bool BaseDesignIntf::canBeSplitted(int height) const +{Q_UNUSED(height); return false;} + +bool BaseDesignIntf::isEmpty() const +{return false;} + +BaseDesignIntf *BaseDesignIntf::cloneUpperPart(int height, QObject *owner, QGraphicsItem *parent) +{Q_UNUSED(height); Q_UNUSED(owner); Q_UNUSED(parent); return 0;} + +BaseDesignIntf *BaseDesignIntf::cloneBottomPart(int height, QObject *owner, QGraphicsItem *parent) +{Q_UNUSED(height); Q_UNUSED(owner); Q_UNUSED(parent); return 0;} + +BaseDesignIntf *BaseDesignIntf::cloneEmpty(int height, QObject *owner, QGraphicsItem *parent) +{Q_UNUSED(height); Q_UNUSED(owner); Q_UNUSED(parent); return 0;} + + +void BaseDesignIntf::objectLoadStarted() +{ + m_objectState = ObjectLoading; +} + +void BaseDesignIntf::objectLoadFinished() +{ + m_objectState = ObjectLoaded; + emit objectLoaded(this); +} + +void BaseDesignIntf::parentObjectLoadFinished() +{} + +QList BaseDesignIntf::childBaseItems() +{ + QList resList; + foreach(QGraphicsItem * item, childItems()) { + BaseDesignIntf *baseItem = dynamic_cast(item); + if (baseItem) resList << baseItem; + } + return resList; +} + +BaseDesignIntf *BaseDesignIntf::childByName(const QString &name) +{ + foreach(BaseDesignIntf* item, childBaseItems()){ + if (item->objectName().compare(name,Qt::CaseInsensitive)==0){ + return item; + } else { + BaseDesignIntf* child = item->childByName(name); + if (child) return child; + } + } + return 0; +} + +QWidget *BaseDesignIntf::defaultEditor() +{ + return 0; +} + +void BaseDesignIntf::notify(const QString &propertyName, const QVariant& oldValue, const QVariant& newValue) +{ + if (!isLoading()) + emit propertyChanged(propertyName, oldValue, newValue); +} + +void BaseDesignIntf::notify(const QVector& propertyNames) +{ + if (!isLoading()) + emit propertyesChanged(propertyNames); +} + +SelectionMarker::SelectionMarker(QGraphicsItem *parent)//, QGraphicsScene *scene) + : QGraphicsItem(parent)//, scene) +{ +} + +QRectF SelectionMarker::boundingRect() const +{ + return m_rect; +} + +void SelectionMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) +{ + QPen pen; + pen.setColor(m_color); + pen.setWidth(2); + pen.setStyle(Qt::DashLine); + painter->setPen(pen); + painter->setOpacity(Consts::SELECTION_COLOR_OPACITY); + painter->drawRect(boundingRect()); +} + + +} + + + + + + + diff --git a/src/lrbasedesignintf.h b/src/lrbasedesignintf.h new file mode 100644 index 0000000..4bca556 --- /dev/null +++ b/src/lrbasedesignintf.h @@ -0,0 +1,333 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRBASEDESIGNINTF_H +#define LRBASEDESIGNINTF_H +#include +#include +#include +#include +#include +#include "lrcollection.h" +#include "lrglobal.h" +#include "serializators/lrstorageintf.h" + +Q_DECLARE_METATYPE(QList*) + +namespace LimeReport { + +enum ItemModes{ DesignMode=1, PreviewMode=2, PrintMode=4, EditMode=8, LayoutEditMode=16 }; + +namespace Consts { + int const RESIZE_HANDLE_SIZE = 10; + int const SELECTION_PEN_SIZE = 4; + int const MINIMUM_ITEM_WIDTH = 2*RESIZE_HANDLE_SIZE; + int const MINIMUM_ITEM_HEIGHT = 2*RESIZE_HANDLE_SIZE; + double const RESIZE_ZONE_OPACITY = 0.5; + double const SELECTED_RESIZE_ZONE_OPACITY = 0.6; + QColor const RESIZE_ZONE_COLOR = Qt::green; + QColor const SELECTION_COLOR = Qt::red; + double const SELECTION_COLOR_OPACITY = 0.9; +} + +class ReportEnginePrivate; +class PageDesignIntf; +class BaseDesignIntf; + +class SelectionMarker : public QGraphicsItem{ +public: + SelectionMarker(QGraphicsItem* parent=0);//, QGraphicsScene* scene=0); + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *); + void setRect(QRectF rect){prepareGeometryChange();m_rect=rect;} + void setColor(QColor color){m_color=color;} +private: + QRectF m_rect; + QColor m_color; + +}; + +class BaseDesignIntf : + public QObject, public QGraphicsItem, public ICollectionContainer, public ObjectLoadingStateIntf { + Q_OBJECT + Q_INTERFACES(QGraphicsItem) + Q_ENUMS(BGMode) + Q_ENUMS(Qt::BrushStyle) + Q_ENUMS(BrushMode) + Q_FLAGS(BorderLines) + Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometryProperty NOTIFY geometryChanged) + Q_PROPERTY(ACollectionProperty children READ fakeCollectionReader DESIGNABLE false) + Q_PROPERTY(qreal zOrder READ zValue WRITE setZValueProperty DESIGNABLE false) + Q_PROPERTY(BorderLines borders READ borderLines WRITE setBorderLinesFlags) + Q_PROPERTY(QString parentName READ parentReportItem WRITE setParentReportItem DESIGNABLE false) +public: + enum BGMode { TransparentMode,OpaqueMode}; + enum BrushMode{Solid,None}; + enum ResizeFlags { Fixed = 0, + ResizeLeft = 1, + ResizeRight = 2, + ResizeTop = 4, + ResizeBottom = 8, + AllDirections = 15 + }; + enum MoveFlags { LeftRight=1, + TopBotom=2, + All=3 + }; + enum BorderSide { TopLine = 1, + BottomLine = 2, + LeftLine = 4, + RightLine = 8 + }; + enum ObjectState {ObjectLoading, ObjectLoaded, ObjectCreated}; + Q_DECLARE_FLAGS(BorderLines, BorderSide) + Q_DECLARE_FLAGS(ItemMode,ItemModes) +public: + BaseDesignIntf(const QString& storageTypeName, QObject* owner = 0, QGraphicsItem* parent = 0); + virtual ~BaseDesignIntf(); + + void setParentReportItem(const QString& value); + QString parentReportItem(); + + BrushMode backgroundBrushMode(){return m_backgroundBrush;} + void setBackgroundBrushMode(BrushMode value); + QColor backgroundColor(){return m_backgroundBrushcolor;} + void setBackgroundColor(QColor value); + + QPen pen() const; + void setPen(QPen& pen); + QFont font() const; + void setFont(QFont& font); + QColor fontColor(){return m_fontColor;} + void setFontColor(QColor value){m_fontColor=value;} + + virtual BGMode backgroundMode() const; + virtual void setBackgroundMode(BGMode bgMode); + virtual qreal width() const; + virtual qreal widthMM() const; + virtual void setWidth(qreal width); + virtual qreal height() const; + virtual qreal heightMM() const; + virtual void setHeight(qreal height); + virtual QPointF posMM() const; + virtual int opacity() const; + virtual void setOpacity(int opacity); + virtual void setSize(QSizeF size); + virtual QSizeF size() const; + virtual QSizeF sizeMM() const; + + void paint(QPainter* ppainter, const QStyleOptionGraphicsItem* option, QWidget* widget); + void prepareRect(QPainter* ppainter, const QStyleOptionGraphicsItem*, QWidget*); + virtual QPainterPath shape() const; + + void setFixedPos(bool fixedPos); + int resizeHandleSize() const; + + void setMMFactor(qreal mmFactor); + qreal mmFactor() const; + virtual QRectF geometry() const; + void setGeometry(QRectF rect); + + QRectF rect()const; + void setupPainter(QPainter* painter) const; + virtual QRectF boundingRect() const; + + virtual void moveRight(); + virtual void moveLeft(); + virtual void moveDown(); + virtual void moveUp(); + + virtual void sizeRight(); + virtual void sizeLeft(); + virtual void sizeUp(); + virtual void sizeDown(); + + void setItemPos(const QPointF &newPos); + void setItemPos(qreal x, qreal y); + + void setItemMode(LimeReport::BaseDesignIntf::ItemMode mode); + ItemMode itemMode() const {return m_itemMode;} + + void setBorderLinesFlags(LimeReport::BaseDesignIntf::BorderLines flags); + void setGeometryProperty(QRectF rect); + PageDesignIntf* page(); + + BorderLines borderLines() const; + QString storageTypeName() const {return m_storageTypeName;} + ReportEnginePrivate *reportEditor(); + + virtual void updateItemSize(RenderPass pass=FirstPass,int maxHeight=0); + virtual bool isNeedUpdateSize(RenderPass) const; + virtual BaseDesignIntf* cloneItem(LimeReport::BaseDesignIntf::ItemMode mode, QObject* owner=0, QGraphicsItem* parent=0); + virtual BaseDesignIntf* cloneItemWOChild(LimeReport::BaseDesignIntf::ItemMode mode, QObject* owner=0, QGraphicsItem* parent=0); + virtual BaseDesignIntf* createSameTypeItem(QObject* owner=0, QGraphicsItem* parent=0) = 0; + void initFromItem(BaseDesignIntf* source); + + virtual bool canBeSplitted(int height) const; + virtual qreal minHeight() const {return 0;} + virtual bool isSplittable() const {return false;} + virtual bool isEmpty() const; + virtual BaseDesignIntf* cloneUpperPart(int height, QObject* owner=0, QGraphicsItem* parent=0); + virtual BaseDesignIntf* cloneBottomPart(int height, QObject* owner=0, QGraphicsItem* parent=0); + virtual BaseDesignIntf* cloneEmpty(int height, QObject* owner=0, QGraphicsItem* parent=0); + + bool isLoaded(){return m_objectState==ObjectLoaded;} + bool isLoading(){return m_objectState==ObjectLoading;} + void objectLoadStarted(); + void objectLoadFinished(); + virtual void parentObjectLoadFinished(); + virtual void beforeDelete(); + + + QList childBaseItems(); + BaseDesignIntf* childByName(const QString& name); + + virtual QWidget *defaultEditor(); + void notify(const QString &propertyName, const QVariant &oldValue, const QVariant &newValue); + void notify(const QVector &propertyNames); + + int posibleResizeDirectionFlags() const; + void setPosibleResizeDirectionFlags(int directionsFlags); + int posibleMoveDirectionFlags() const; + void setPosibleMoveFlags(int directionsFlags); + + int marginSize() const {return m_margin;} + void setMarginSize(int value); + + QString itemTypeName() const; + void setItemTypeName(const QString &itemTypeName); + void emitObjectNamePropertyChanged(const QString& oldName, const QString& newName); +protected: + + //ICollectionContainer + QObject* createElement(const QString&, const QString& elementType); + int elementsCount(const QString&); + QObject* elementAt(const QString&, int index); + void collectionLoadFinished(const QString& collectionName); + //ICollectionContainer + + void mousePressEvent(QGraphicsSceneMouseEvent* event); + void hoverMoveEvent(QGraphicsSceneHoverEvent* event); + void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); + //void virtual hoverEnterEvent(QGraphicsSceneHoverEvent *event); + void mouseMoveEvent(QGraphicsSceneMouseEvent* event); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); + + virtual void geometryChangedEvent(QRectF newRect, QRectF oldRect); + virtual QPen borderPen(BorderSide side) const; + virtual QColor selectionColor() const; + virtual void initFlags(); + virtual void initMode(LimeReport::BaseDesignIntf::ItemMode mode); + virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + virtual void childAddedEvent(BaseDesignIntf* child); + + void drawTopLine(QPainter *painter, QRectF rect) const; + void drawBootomLine(QPainter *painter, QRectF rect) const; + void drawRightLine(QPainter *painter, QRectF rect) const; + void drawLeftLine(QPainter *painter, QRectF rect) const; + + void drawBorder(QPainter* painter, QRectF rect) const; + void drawDesignModeBorder(QPainter* painter, QRectF rect) const; + void drawRenderModeBorder(QPainter *painter, QRectF rect) const; + void drawResizeZone(QPainter *painter); + void drawSelection(QPainter* painter, QRectF) const; + void drawPinArea(QPainter* painter) const; + + void initResizeZones(); + void invalidateRect(const QRectF &rect); + void invalidateRects(QVector rects); + QFont transformToSceneFont(const QFont &value) const; + + RenderPass currentRenderPass(){return m_currentPass;} + +private: + void updateSelectionMarker(); + int resizeDirectionFlags(QPointF position); + void moveSelectedItems(QPointF delta); + Qt::CursorShape getPosibleCursor(int cursorFlags); + void setZValueProperty(qreal value); +private slots: +// void slotObjectNameChanged(const QString& newName); +private: + QPointF m_startPos; + QPointF m_startScenePos; + int m_resizeHandleSize; + int m_selectionPenSize; + int m_posibleResizeDirectionFlags; + int m_posibleMoveDirectionFlags; + int m_resizeDirectionFlags; + qreal m_width, m_height; + QPen m_pen; + QFont m_font; + QColor m_fontColor; + qreal m_mmFactor; + bool m_fixedPos; + + QRectF m_rect; + mutable QRectF m_boundingRect; + + QRectF m_oldGeometry; + BGMode m_BGMode; + int m_opacity; + BorderLines m_borderLinesFlags; + + QRectF m_bottomRect; + QRectF m_topRect; + QRectF m_leftRect; + QRectF m_rightRect; + + QVector m_resizeAreas; + QFrame* m_hintFrame; + QString m_storageTypeName; + ItemMode m_itemMode; + + ObjectState m_objectState; + SelectionMarker* m_selectionMarker; + + BrushMode m_backgroundBrush; + QColor m_backgroundBrushcolor; + RenderPass m_currentPass; + int m_margin; + QString m_itemTypeName; +signals: + void geometryChanged(QObject* object, QRectF newGeometry, QRectF oldGeometry); + void posChanged(QObject* object, QPointF newPos, QPointF oldPos); + void itemSelected(LimeReport::BaseDesignIntf *item); + void loadCollectionFinished(const QString& collectionName); + void objectLoaded(QObject* object); + void objectChanged(QObject* object); + void propertyChanged(const QString& propertName, const QVariant& oldValue,const QVariant& newValue); + void propertyObjectNameChanged(const QString& oldValue, const QString& newValue); + void propertyesChanged(QVector propertyNames); +}; + +} //namespace LimeReport + +#endif // LRBASEDESIGNINTF_H diff --git a/src/lrcallbackdatasourceintf.h b/src/lrcallbackdatasourceintf.h new file mode 100644 index 0000000..3259f4b --- /dev/null +++ b/src/lrcallbackdatasourceintf.h @@ -0,0 +1,24 @@ +#ifndef LRVIRTUALDATASOURCEINTF +#define LRVIRTUALDATASOURCEINTF +#include +namespace LimeReport { + +struct CallbackInfo{ + enum DataType{IsEmpty, HasNext, ColumnHeaderData, ColumnData}; + enum ChangePosType{First, Next}; + DataType dataType; + int index; + QString columnName; +}; + +class ICallbackDatasource :public QObject{ + Q_OBJECT +signals: + void getCallbackData(const LimeReport::CallbackInfo& info, QVariant& data); + void changePos(const LimeReport::CallbackInfo::ChangePosType& type, bool& result); +}; + +} + +#endif // LRVIRTUALDATASOURCEINTF + diff --git a/src/lrcollection.h b/src/lrcollection.h new file mode 100644 index 0000000..0422c28 --- /dev/null +++ b/src/lrcollection.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRCOLLECTION_H +#define LRCOLLECTION_H + +#include +#include + +class ACollectionProperty{ +public: + ACollectionProperty(){} + ACollectionProperty(const ACollectionProperty& ){} + virtual ~ACollectionProperty(){} +}; +Q_DECLARE_METATYPE(ACollectionProperty) + +namespace LimeReport{ + +const int COLLECTION_TYPE_ID = qMetaTypeId(); +class ICollectionContainer{ +public: + virtual QObject* createElement(const QString& collectionName,const QString& elementType)=0; + virtual int elementsCount(const QString& collectionName)=0; + virtual QObject* elementAt(const QString& collectionName,int index)=0; + virtual void collectionLoadFinished(const QString& collectionName){Q_UNUSED(collectionName)} + ACollectionProperty fakeCollectionReader(){return ACollectionProperty();} +}; + +} +#endif // LRCOLLECTION_H diff --git a/src/lrdatadesignintf.cpp b/src/lrdatadesignintf.cpp new file mode 100644 index 0000000..c78b249 --- /dev/null +++ b/src/lrdatadesignintf.cpp @@ -0,0 +1,583 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrdatadesignintf.h" + +#include +#include +#include +#include +#include +#include "lrdatasourcemanager.h" + +namespace LimeReport{ + +ModelHolder::ModelHolder(QAbstractItemModel *model, bool owned /*false*/) +{ + ModelToDataSource* mh = new ModelToDataSource(model,owned); + m_dataSource = mh; + m_owned=owned; + connect(mh, SIGNAL(modelStateChanged()), this, SIGNAL(modelStateChanged())); +} + +ModelHolder::~ModelHolder(){ + delete m_dataSource; +} + +IDataSource * ModelHolder::dataSource(IDataSource::DatasourceMode mode) +{ + Q_UNUSED(mode); + return m_dataSource; +} + +QueryHolder::QueryHolder(QString queryText, QString connectionName) + : m_query(0), m_queryText(queryText), m_connectionName(connectionName), m_mode(IDataSource::RENDER_MODE) +{ + extractParams(); +} + +QueryHolder::~QueryHolder() +{ + if (m_query) delete m_query; +} + +bool QueryHolder::runQuery(IDataSource::DatasourceMode mode) +{ + m_mode = mode; + QSqlDatabase db = QSqlDatabase::database(m_connectionName); + if (!db.isValid()) { + setLastError(QObject::tr("Invalid connection! %1").arg(m_connectionName)); + return false; + } + + if (!m_query){ + m_query = new QSqlQuery(db); + m_query->prepare(m_preparedSQL); + } + + fillParams(m_query); + m_query->exec(); + + QSqlQueryModel *model = new QSqlQueryModel; + model->setQuery(*m_query); + + while (model->canFetchMore()) + model->fetchMore(); + + if (model->lastError().isValid()){ + if (m_dataSource) + m_dataSource.clear(); + setLastError(model->lastError().text()); + delete model; + return false; + } else setLastError(""); + + setDatasource(IDataSource::Ptr(new ModelToDataSource(model,true))); + return true; +} + +QString QueryHolder::connectionName() +{ + return m_connectionName; +} + +void QueryHolder::setConnectionName(QString connectionName) +{ + m_connectionName=connectionName; +} + +void QueryHolder::setDatasource(IDataSource::Ptr value){ + m_dataSource.clear(); + m_dataSource=value; +} + +void QueryHolder::fillParams(QSqlQuery *query) +{ + DataSourceManager* dm=DataSourceManager::instance(); + foreach(QString param,m_params){ + QVariant value; + if (param.contains(".")){ + value = dm->fieldData(param); + param=param.right(param.length()-param.indexOf('.')-1); + } else { + value = dm->variable(param); + } + if (value.isValid() || m_mode == IDataSource::DESIGN_MODE) + query->bindValue(':'+param,value); + } +} + +void QueryHolder::extractParams() +{ + m_preparedSQL = replaceVriables(m_queryText); +} + +QString QueryHolder::replaceVriables(QString query) +{ + QRegExp rx(VARIABLE_RX); + if (query.contains(rx)){ + while ((rx.indexIn(query))!=-1){ + QString variable=rx.cap(0); + variable.remove("$V{"); + variable.remove("}"); + m_params.append(variable); + query.replace(rx.cap(0),":"+variable); + } + } + return query; +} + +QString QueryHolder::queryText() +{ + return m_queryText; +} + +void QueryHolder::setQueryText(QString queryText) +{ + m_queryText=queryText; +} + +IDataSource* QueryHolder::dataSource(IDataSource::DatasourceMode mode) +{ + if ((m_mode != mode && m_mode == IDataSource::DESIGN_MODE) || m_dataSource==0) { + m_mode = mode; + runQuery(mode); + } + if (m_dataSource) + return m_dataSource.data(); + else return 0; +} + +// QueryHolder + +// ModelToDataSource + +ModelToDataSource::ModelToDataSource(QAbstractItemModel* model, bool owned) + : QObject(), m_model(model), m_owned(owned), m_curRow(-1), m_lastError("") +{ + Q_ASSERT(model); + if (model){ + while (model->canFetchMore(QModelIndex())) + model->fetchMore(QModelIndex()); + connect(model, SIGNAL(destroyed()), this, SLOT(slotModelDestroed())); + connect(model, SIGNAL(modelReset()), this, SIGNAL(modelStateChanged())); + } +} + +ModelToDataSource::~ModelToDataSource() +{ + if ((m_owned) && m_model!=0) + delete m_model; +} + +bool ModelToDataSource::next() +{ + if (isInvalid()) return false; + if (m_curRow<(m_model->rowCount())) { + if (bof()) m_curRow++; + m_curRow++; + return true; + } else return false; +} + +bool ModelToDataSource::hasNext() +{ + if (isInvalid()) return false; + return m_curRowrowCount()-1; +} + +bool ModelToDataSource::prior() +{ + if (isInvalid()) return false; + if (m_curRow>-1){ + if (eof()) m_curRow--; + m_curRow--; + return true; + } else return false; +} + +void ModelToDataSource::first() +{ + m_curRow=0; +} + +void ModelToDataSource::last() +{ + if (isInvalid()) m_curRow=0; + else m_curRow=m_model->rowCount()-1; +} + +bool ModelToDataSource::eof() +{ + if (isInvalid()) return true; + return (m_curRow==m_model->rowCount())||(m_model->rowCount()==0); +} + +bool ModelToDataSource::bof() +{ + if (isInvalid()) return true; + return (m_curRow==-1)||(m_model->rowCount()==0); +} + +QVariant ModelToDataSource::data(const QString &columnName) +{ + if (isInvalid()) return QVariant(); + return m_model->data(m_model->index(currentRow(),columnIndexByName(columnName))); +} + +int ModelToDataSource::columnCount() +{ + if (isInvalid()) return 0; + return m_model->columnCount(); +} + +QString ModelToDataSource::columnNameByIndex(int columnIndex) +{ + if (isInvalid()) return ""; + return m_model->headerData(columnIndex,Qt::Horizontal).toString(); +} + +int ModelToDataSource::columnIndexByName(QString name) +{ + if (isInvalid()) return 0; + for(int i=0;icolumnCount();i++){ + if (m_model->headerData(i,Qt::Horizontal).toString().compare(name,Qt::CaseInsensitive)==0) + return i; + } + return -1; +} + +QString ModelToDataSource::lastError() +{ + return m_lastError; +} + +QAbstractItemModel * ModelToDataSource::model() +{ + return m_model; +} + +int ModelToDataSource::currentRow() +{ + if (eof()) return m_curRow-1; + if (bof()) return m_curRow+1; + return m_curRow; +} + +bool ModelToDataSource::isInvalid() const +{ + return m_model==0; +} + +void ModelToDataSource::slotModelDestroed() +{ + m_model = 0; + m_lastError = tr("model is destroyed"); + emit modelStateChanged(); +} + +ConnectionDesc::ConnectionDesc(QSqlDatabase db, QObject *parent) + : QObject(parent), m_connectionName(db.connectionName()), m_connectionHost(db.hostName()), m_connectionDriver(db.driverName()), + m_databaseName(db.databaseName()), m_user(db.userName()), m_password(db.password()) +{} + +ConnectionDesc::ConnectionDesc(QObject *parent) + :QObject(parent),m_connectionName(""),m_connectionHost(""),m_connectionDriver(""), + m_databaseName(""), m_user(""), m_password(""), m_autoconnect(false) +{} + +ConnectionDesc::Ptr ConnectionDesc::create(QSqlDatabase db, QObject *parent) +{ + return Ptr(new ConnectionDesc(db,parent)); +} + +void ConnectionDesc::setName(const QString &value) +{ + if (m_connectionName!=value) emit nameChanged(m_connectionName,value); + m_connectionName=value; +} + +QueryDesc::QueryDesc(QString queryName, QString queryText, QString connection) + :m_queryName(queryName), m_query(queryText), m_connectionName(connection) +{} + +SubQueryHolder::SubQueryHolder(QString queryText, QString connectionName, QString masterDatasource) + : QueryHolder(queryText,connectionName), m_masterDatasource(masterDatasource), m_invalid(false) +{ + extractParams(); +} + +void SubQueryHolder::setMasterDatasource(const QString &value) +{ + DataSourceManager* dm = DataSourceManager::instance(); + if (dm->dataSource(value)){ + m_masterDatasource = value; + m_invalid = false; + } +} + +void SubQueryHolder::extractParams() +{ + m_preparedSQL = replaceFields(replaceVriables(queryText())); +} + +QString SubQueryHolder::extractField(QString source) +{ + if (source.contains('.')) { + return source.right(source.length()-(source.indexOf('.')+1)); + } + return source; +} + +QString SubQueryHolder::replaceFields(QString query) +{ + QRegExp rx(FIELD_RX); + if (query.contains(rx)){ + while ((rx.indexIn(query))!=-1){ + QString field=rx.cap(0); + field.remove("$D{"); + field.remove("}"); + if (field.contains(".")) + m_params.append(field); + else + m_params.append(m_masterDatasource+"."+field); + query.replace(rx.cap(0),":"+extractField(field)); + } + } + return query; +} + +SubQueryDesc::SubQueryDesc(QString queryName, QString queryText, QString connection, QString masterDatasourceName) + :QueryDesc(queryName,queryText,connection), m_masterDatasourceName(masterDatasourceName) +{ +} + +QObject *ProxyDesc::createElement(const QString &collectionName, const QString &) +{ + if (collectionName=="fields"){ + FieldMapDesc* fieldMapDesc = new FieldMapDesc; + m_maps.append(fieldMapDesc); + return fieldMapDesc; + } + return 0; +} + +int ProxyDesc::elementsCount(const QString &collectionName) +{ + Q_UNUSED(collectionName) + return m_maps.count(); +} + +QObject *ProxyDesc::elementAt(const QString &collectionName, int index) +{ + Q_UNUSED(collectionName) + return m_maps.at(index); +} + +ProxyHolder::ProxyHolder(ProxyDesc* desc) + :m_desc(desc), m_lastError(""), m_mode(IDataSource::RENDER_MODE), m_invalid(false) +{} + +QString ProxyHolder::masterDatasource() +{ + if (m_desc) return m_desc->master(); + return QString(); +} + +void ProxyHolder::filterModel() +{ + if (!m_datasource){ + DataSourceManager* dm=DataSourceManager::instance(); + if (dm){ + IDataSource* master = dm->dataSource(m_desc->master()); + IDataSource* child = dm->dataSource(m_desc->child()); + if (master&&child){ + m_model = new MasterDetailProxyModel(); + connect(child->model(),SIGNAL(destroyed()), this, SLOT(slotChildModelDestoroyed())); + m_model->setSourceModel(child->model()); + m_model->setMaster(m_desc->master()); + m_model->setChildName(m_desc->child()); + m_model->setFieldsMap(m_desc->fieldsMap()); + try{ + m_model->rowCount(); + m_datasource = IDataSource::Ptr(new ModelToDataSource(m_model,true)); + } catch (ReportError& exception) { + m_lastError = exception.what(); + } + } else { + m_lastError.clear(); + if(!master) m_lastError+=QObject::tr("Master datasouce \"%1\" not found!").arg(m_desc->master()); + if(!child) m_lastError+=((m_lastError.isEmpty())?QObject::tr("Child"):QObject::tr(" and child "))+ + QObject::tr("datasouce \"%1\" not found!").arg(m_desc->child()); + } + } + } else { + if (!isInvalid()){ + m_model->invalidate(); + m_datasource->first(); + } + } +} + +IDataSource *ProxyHolder::dataSource(IDataSource::DatasourceMode mode) +{ + if ((m_mode != mode && m_mode == IDataSource::DESIGN_MODE) || m_datasource==0) { + m_mode = mode; + m_datasource.clear(); + filterModel(); + } + return m_datasource.data(); +} + +void ProxyDesc::addFieldsCorrelation(const FieldsCorrelation& fieldsCorrelation) +{ + m_maps.append(new FieldMapDesc(fieldsCorrelation)); +} + +void MasterDetailProxyModel::setMaster(QString name){ + m_masterName=name; +} + +bool MasterDetailProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const +{ + Q_UNUSED(source_parent) + foreach (FieldMapDesc* fieldCorrelation, *m_maps) { + QVariant master = masterData(fieldCorrelation->master()); + QVariant detail = sourceData(fieldCorrelation->detail(),source_row); + if (master==detail) + return true; + } + return false; +} + +int MasterDetailProxyModel::fieldIndexByName(QString fieldName) const +{ + for(int i=0;icolumnCount();++i){ + if (sourceModel()->headerData(i,Qt::Horizontal).toString().compare(fieldName,Qt::CaseInsensitive)==0){ + return i; + } + } + return -1; +} + +QVariant MasterDetailProxyModel::sourceData(QString fieldName, int row) const +{ + int fieldIndex = fieldIndexByName(fieldName); + if (fieldIndex!=-1){ + return sourceModel()->index(row,fieldIndex).data(); + } else { + throw ReportError( + tr("Field: \"%1\" not found in \"%2\" child datasource").arg(fieldName).arg(m_childName) + ); + } +} + +QVariant MasterDetailProxyModel::masterData(QString fieldName) const +{ + IDataSource* master = DataSourceManager::instance()->dataSource(m_masterName); + int columnIndex = master->columnIndexByName(fieldName); + if (columnIndex!=-1){ + return master->data(fieldName); + } else { + throw ReportError( + tr("Field: \"%1\" not found in \"%2\" master datasource").arg(fieldName).arg(m_masterName) + ); + } +} + +bool CallbackDatasource::next(){ + if (!m_eof){ + m_currentRow++; + bool result = false; + emit changePos(CallbackInfo::Next,result); + m_eof = !checkNextRecord(m_currentRow); + return result; + } else return false; +} + +void CallbackDatasource::first(){ + m_currentRow = 0; + m_eof=checkIfEmpty(); + bool result=false; + emit changePos(CallbackInfo::First,result); + m_eof = !result; +} + +QVariant CallbackDatasource::data(const QString& columnName) +{ + CallbackInfo info; + info.dataType = CallbackInfo::ColumnData; + info.columnName = columnName; + info.index = m_currentRow; + QVariant result; + emit getCallbackData(info,result); + return result; +} + +int CallbackDatasource::columnCount(){ + if (m_headers.size()==0){ + int currIndex = 0; + do { + QVariant columnName; + CallbackInfo info; + info.dataType = CallbackInfo::ColumnHeaderData; + info.index = currIndex; + emit getCallbackData(info,columnName); + if (columnName.isValid()){ + m_headers.append(columnName.toString()); + currIndex++; + } else break; + } while (true); + } + return m_headers.size(); +} + +QString CallbackDatasource::columnNameByIndex(int columnIndex) +{ + if (columnIndex < m_headers.size()) + return m_headers[columnIndex]; + else return QString(); +} + +int CallbackDatasource::columnIndexByName(QString name) +{ + for (int i=0;i. * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRDATADESIGNINTF_H +#define LRDATADESIGNINTF_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "lrcollection.h" +#include "lrcallbackdatasourceintf.h" + +namespace LimeReport{ + +class IDataSource { +public: + enum DatasourceMode{DESIGN_MODE,RENDER_MODE}; + typedef QSharedPointer Ptr; + virtual ~IDataSource(){} + virtual bool next() = 0; + virtual bool hasNext() = 0; + virtual bool prior() = 0; + virtual void first() = 0; + virtual void last() = 0; + virtual bool bof() = 0; + virtual bool eof() = 0; + virtual QVariant data(const QString& columnName) = 0; + virtual int columnCount() = 0; + virtual QString columnNameByIndex(int columnIndex) = 0; + virtual int columnIndexByName(QString name) = 0; + virtual bool isInvalid() const = 0; + virtual QString lastError() = 0; + virtual QAbstractItemModel* model() = 0; +}; + +class IDataSourceHolder { +public: + virtual IDataSource* dataSource(IDataSource::DatasourceMode mode = IDataSource::RENDER_MODE) = 0; + virtual QString lastError() const = 0; + virtual bool isInvalid() const = 0; + virtual bool isOwned() const = 0; + virtual bool isEditable() const = 0; + virtual bool isRemovable() const = 0; + virtual void invalidate() = 0; + virtual ~IDataSourceHolder(){} +}; + +class ModelHolder: public QObject, public IDataSourceHolder{ + Q_OBJECT +public: + ModelHolder(QAbstractItemModel* model, bool owned=false); + ~ModelHolder(); + IDataSource* dataSource(IDataSource::DatasourceMode mode); + bool isOwned() const { return m_owned; } + bool isInvalid() const { return m_dataSource->isInvalid(); } + QString lastError() const { return m_dataSource->lastError(); } + bool isEditable() const { return false; } + bool isRemovable() const { return false; } + void invalidate(){} +signals: + void modelStateChanged(); +private: + IDataSource* m_dataSource; + bool m_owned; +}; + +class ConnectionDesc : public QObject{ + Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName ) + Q_PROPERTY(QString driver READ driver WRITE setDriver) + Q_PROPERTY(QString databaseName READ databaseName WRITE setDatabaseName) + Q_PROPERTY(QString userName READ userName WRITE setUserName) + Q_PROPERTY(QString password READ password WRITE setPassword) + Q_PROPERTY(QString host READ host WRITE setHost) + Q_PROPERTY(bool autoconnect READ autoconnect WRITE setAutoconnect) +public: + typedef QSharedPointer Ptr; + ConnectionDesc(QSqlDatabase db, QObject* parent=0); + ConnectionDesc(QObject* parent=0); + Ptr create(QSqlDatabase db, QObject* parent=0); + void setName(const QString &value); + QString name(){return m_connectionName;} + void setDriver(const QString &value){m_connectionDriver=value;} + QString driver(){return m_connectionDriver;} + void setHost(const QString &value){m_connectionHost=value;} + QString host(){return m_connectionHost;} + void setDatabaseName(const QString &value){m_databaseName=value;} + QString databaseName(){return m_databaseName;} + void setUserName(const QString &value){m_user=value;} + QString userName(){return m_user;} + void setPassword(const QString &value){m_password=value;} + QString password(){return m_password;} + void setAutoconnect(bool value){m_autoconnect=value;} + bool autoconnect(){return m_autoconnect;} +signals: + void nameChanged(const QString& oldName,const QString& newName); +private: + QString m_connectionName; + QString m_connectionHost; + QString m_connectionDriver; + QString m_databaseName; + QString m_user; + QString m_password; + bool m_autoconnect; +}; + +class IConnectionController{ +public: + virtual void addConnectionDesc(ConnectionDesc* connection) = 0; + virtual void changeConnectionDesc(ConnectionDesc* connection) = 0; +}; + +class QueryDesc : public QObject{ + Q_OBJECT + Q_PROPERTY(QString queryName READ queryName WRITE setQueryName) + Q_PROPERTY(QString queryText READ queryText WRITE setQueryText) + Q_PROPERTY(QString connectionName READ connectionName WRITE setConnectionName) +public: + QueryDesc(QString queryName, QString queryText, QString connection); + explicit QueryDesc(QObject* parent=0):QObject(parent){} + void setQueryName(QString value){m_queryName=value;} + QString queryName(){return m_queryName;} + void setQueryText(QString value){m_query=value;} + QString queryText(){return m_query;} + void setConnectionName(QString value){m_connectionName=value;} + QString connectionName(){return m_connectionName;} +private: + QString m_queryName; + QString m_query; + QString m_connectionName; +}; + +class QueryHolder:public IDataSourceHolder{ +public: + QueryHolder(QString queryText, QString connectionName); + ~QueryHolder(); + virtual bool runQuery(IDataSource::DatasourceMode mode = IDataSource::RENDER_MODE); + IDataSource* dataSource(IDataSource::DatasourceMode mode = IDataSource::RENDER_MODE); + QString connectionName(); + QString queryText(); + void setQueryText(QString queryText); + void setConnectionName(QString connectionName); + bool isOwned() const { return true; } + bool isInvalid() const { return !m_lastError.isEmpty(); } + bool isEditable() const { return true; } + bool isRemovable() const { return true; } + QString lastError() const { return m_lastError; } + void setLastError(QString value){m_lastError=value; if (m_query) {delete m_query; m_query=0;}} + void invalidate(){} +protected: + void setDatasource(IDataSource::Ptr value); + virtual void fillParams(QSqlQuery* query); + virtual void extractParams(); + QString replaceVriables(QString query); + QList m_params; + QSqlQuery* m_query; + QString m_preparedSQL; +private: + QString m_queryText; + QString m_connectionName; + QString m_lastError; + IDataSource::Ptr m_dataSource; + IDataSource::DatasourceMode m_mode; +}; + +class SubQueryDesc : public QueryDesc{ + Q_OBJECT + Q_PROPERTY(QString master READ master WRITE setMaster) +public: + SubQueryDesc(QString queryName, QString queryText, QString connection, QString master); + explicit SubQueryDesc(QObject* parent=0):QueryDesc(parent){} + void setMaster(QString value){m_masterDatasourceName=value;} + QString master(){return m_masterDatasourceName;} +private: + QString m_masterDatasourceName; +}; + +class SubQueryHolder:public QueryHolder{ +public: + SubQueryHolder(QString queryText, QString connectionName, QString masterDatasource); + QString masterDatasource(){return m_masterDatasource;} + void setMasterDatasource(const QString& value); + void invalidate(){m_invalid = true;} + bool isInvalid() const{ return QueryHolder::isInvalid() || m_invalid;} +protected: + void extractParams(); + QString extractField(QString source); + QString replaceFields(QString query); +private: + QString m_masterDatasource; + bool m_invalid; +}; + +struct FieldsCorrelation{ + QString master; + QString detail; +}; + +class FieldMapDesc : public QObject{ + Q_OBJECT + Q_PROPERTY(QString master READ master WRITE setMaster) + Q_PROPERTY(QString detail READ detail WRITE setDetail) +public: + FieldMapDesc(){} + FieldMapDesc(FieldsCorrelation correlation):m_fieldsCorrelation(correlation){} + QString master(){return m_fieldsCorrelation.master;} + void setMaster(QString value){m_fieldsCorrelation.master=value;} + QString detail(){return m_fieldsCorrelation.detail;} + void setDetail(QString value){m_fieldsCorrelation.detail=value;} +private: + FieldsCorrelation m_fieldsCorrelation; +}; + +class ProxyDesc : public QObject, public ICollectionContainer{ + Q_OBJECT + Q_PROPERTY(ACollectionProperty fields READ fakeCollectionReader) + Q_PROPERTY(QString master READ master WRITE setMaster) + Q_PROPERTY(QString child READ child WRITE setDetail) + Q_PROPERTY(QString name READ name WRITE setName) +public: + void setMaster(QString value){m_master=value;} + QString master(){return m_master;} + void setDetail(QString value){m_detail=value;} + QString child(){return m_detail;} + QString name(){return m_name;} + void setName(QString value){m_name=value;} + void addFieldsCorrelation(const FieldsCorrelation &fieldsCorrelation); + QList* fieldsMap(){return &m_maps;} + //ICollectionContainer + virtual QObject* createElement(const QString& collectionName,const QString&); + virtual int elementsCount(const QString& collectionName); + virtual QObject *elementAt(const QString& collectionName,int index); +private: + QList m_maps; + QString m_master; + QString m_detail; + QString m_name; +}; + +class MasterDetailProxyModel : public QSortFilterProxyModel{ +public: + MasterDetailProxyModel():m_maps(0){} + void setMaster(QString name); + void setChildName(QString name){m_childName=name;} + void setFieldsMap(QList *fieldsMap){m_maps=fieldsMap;} +protected: + bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; + int fieldIndexByName(QString fieldName) const; + QVariant sourceData(QString fieldName, int row) const; + QVariant masterData(QString fieldName) const; +private: + QList* m_maps; + QString m_masterName; + QString m_childName; + +}; + +class ProxyHolder: public QObject, public IDataSourceHolder{ + Q_OBJECT +public: + ProxyHolder(ProxyDesc *desc); + QString masterDatasource(); + void filterModel(); + IDataSource* dataSource(IDataSource::DatasourceMode mode = IDataSource::RENDER_MODE); + bool isOwned() const { return true; } + bool isInvalid() const { return !m_lastError.isEmpty() || m_invalid; } + bool isEditable() const { return true; } + bool isRemovable() const { return true; } + QString lastError() const { return m_lastError; } + void invalidate(){m_invalid = true; m_lastError = tr("Datasource has been invalidated");} +private slots: + void slotChildModelDestoroyed(){m_datasource.clear();} +private: + IDataSource::Ptr m_datasource; + MasterDetailProxyModel *m_model; + ProxyDesc *m_desc; + QString m_lastError; + IDataSource::DatasourceMode m_mode; + bool m_invalid; +}; + +class ModelToDataSource : public QObject, public IDataSource{ + Q_OBJECT +public: + ModelToDataSource(QAbstractItemModel* model, bool owned); + ~ModelToDataSource(); + bool next(); + bool hasNext(); + bool prior(); + void first(); + void last(); + bool eof(); + bool bof(); + QVariant data(const QString& columnName); + int columnCount(); + QString columnNameByIndex(int columnIndex); + int columnIndexByName(QString name); + QString lastError(); + virtual QAbstractItemModel* model(); + int currentRow(); + bool isInvalid() const; +signals: + void modelStateChanged(); +private slots: + void slotModelDestroed(); +private: + QAbstractItemModel* m_model; + bool m_owned; + int m_curRow; + QString m_lastError; +}; + +class CallbackDatasource :public ICallbackDatasource, public IDataSource { + Q_OBJECT +public: + CallbackDatasource(): m_currentRow(-1), m_eof(false){} + bool next(); + bool hasNext(){ return !m_eof;} + bool prior(){ if (m_currentRow !=-1) {m_currentRow--; return true;} else return false;} + void first(); + void last(){} + bool bof(){return m_currentRow == -1;} + bool eof(){return m_eof;} + QVariant data(const QString &columnName); + int columnCount(); + QString columnNameByIndex(int columnIndex); + int columnIndexByName(QString name); + bool isInvalid() const{ return false;} + QString lastError(){ return "";} + QAbstractItemModel *model(){return 0;} +private: + bool checkNextRecord(int recordNum){ + QVariant result = false; + CallbackInfo info; + info.dataType = CallbackInfo::HasNext; + info.index = recordNum; + emit getCallbackData(info,result); + return result.toBool(); + } + bool checkIfEmpty(){ + QVariant result = true; + CallbackInfo info; + info.dataType = CallbackInfo::IsEmpty; + emit getCallbackData(info,result); + //emit getIsEmpty(result); + return result.toBool(); + } +private: + QVector m_headers; + int m_currentRow; + bool m_eof; +}; + +class CallbackDatasourceHolder :public QObject, public IDataSourceHolder{ + Q_OBJECT + // IDataSourceHolder interface +public: + CallbackDatasourceHolder(IDataSource* datasource, bool owned):m_owned(owned){ m_datasource = datasource;} + IDataSource *dataSource(IDataSource::DatasourceMode){ return m_datasource;} + QString lastError() const{ return m_datasource->lastError();} + bool isInvalid() const {return m_datasource->isInvalid();} + bool isOwned() const {return m_owned;} + bool isEditable() const {return false;} + bool isRemovable() const {return false;} + void invalidate(){} + ~CallbackDatasourceHolder(){if (m_datasource) delete m_datasource;} +private: + IDataSource* m_datasource; + bool m_owned; +}; + +} +#endif // LRDATADESIGNINTF_H diff --git a/src/lrdatasourcemanager.cpp b/src/lrdatasourcemanager.cpp new file mode 100644 index 0000000..1db8034 --- /dev/null +++ b/src/lrdatasourcemanager.cpp @@ -0,0 +1,1035 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrdatasourcemanager.h" +#include "lrdatadesignintf.h" +#include +#include +#include +#include +#include + +namespace LimeReport{ + +DataNode::~DataNode() +{ + for (int i = 0; im_childs.indexOf(const_cast(this)); + } + return 0; +} + +void DataNode::clear() +{ + for (int i=0; ichild(row); + if (childNode){ + return createIndex(row,column,childNode); + } else return QModelIndex(); +} + +QModelIndex DataSourceModel::parent(const QModelIndex& child) const +{ + if (!child.isValid()) return QModelIndex(); + + DataNode* childNode = nodeFromIndex(child); + if (!childNode) return QModelIndex(); + + DataNode* parentNode = childNode->parent(); + if ((parentNode == m_rootNode) || (!parentNode)) return QModelIndex(); + return createIndex(parentNode->row(),0,parentNode); +} + +int DataSourceModel::rowCount(const QModelIndex& parent) const +{ + if (!m_rootNode) return 0; + DataNode* parentNode; + if (parent.isValid()) + parentNode = nodeFromIndex(parent); + else + parentNode = m_rootNode; + return parentNode->childCount(); +} + +int DataSourceModel::columnCount(const QModelIndex& parent) const +{ + Q_UNUSED(parent) + return 1; +} + +QVariant DataSourceModel::data(const QModelIndex& index, int role) const +{ + DataNode *node = nodeFromIndex(index); + switch (role) { + case Qt::DisplayRole: + if (!node) return QVariant(); + return node->name(); + break; + case Qt::DecorationRole : + if (!node) return QIcon(); + return node->icon(); + break; + default: + return QVariant(); + } +} + +void DataSourceModel::setDataSourceManager(DataSourceManager* dataManager) +{ + m_dataManager = dataManager; + connect(m_dataManager,SIGNAL(datasourcesChanged()),this,SLOT(slotDatasourcesChanged())); + updateModel(); +} + +void DataSourceModel::slotDatasourcesChanged() +{ + beginResetModel(); + updateModel(); + endResetModel(); +} + +DataNode* DataSourceModel::nodeFromIndex(const QModelIndex& index) const +{ + if (index.isValid()){ + return static_cast(index.internalPointer()); + } else return m_rootNode; +} + +void DataSourceModel::fillFields(DataNode* parent) +{ + foreach(QString name, m_dataManager->fieldNames(parent->name())){ + parent->addChild(name,DataNode::Field,QIcon(":/report/images/field")); + } +} + +void DataSourceModel::updateModel() +{ + QMap connections; + + m_rootNode->clear(); + DataNode* ds = m_rootNode->addChild(tr("Datasources"),DataNode::DataSources,QIcon(":/report/images/databases")); + + + foreach (QString name,m_dataManager->connectionNames()) { + DataNode* connection = ds->addChild(name,DataNode::Connection,QIcon(":/report/images/database")); + connections.insert(name,connection); + } + + foreach (QString name, m_dataManager->dataSourceNames()) { + DataNode* datasource; + if (m_dataManager->isQuery(name)){ + DataNode* connection = connections.value(m_dataManager->queryByName(name)->connectionName()); + if (connection) datasource=connection->addChild(name,DataNode::Query,QIcon(":/report/images/table")); + else datasource=ds->addChild(name,DataNode::Query); + } else if (m_dataManager->isSubQuery(name)){ + DataNode* connection = connections.value(m_dataManager->subQueryByName(name)->connectionName()); + if (connection) datasource=connection->addChild(name,DataNode::SubQuery,QIcon(":/report/images/table")); + else datasource=ds->addChild(name,DataNode::SubQuery); + } else { + datasource=ds->addChild(name,DataNode::Model,QIcon(":/report/images/table")); + } + fillFields(datasource); + } + + DataNode* vars = m_rootNode->addChild(tr("Variables"),DataNode::Variables,QIcon(":/report/images/folder")); + foreach (QString name, m_dataManager->variableNames()){ + vars->addChild(name,DataNode::Variable,QIcon(":/report/images/value")); + } +} + +DataSourceManager* DataSourceManager::m_instance=0; + +DataSourceManager::DataSourceManager(QObject *parent) : + QObject(parent), m_lastError(""), m_designTime(true) +{ + m_instance=this; + m_groupFunctionFactory.registerFunctionCreator(QLatin1String("COUNT"),new ConstructorGroupFunctionCreator); + m_groupFunctionFactory.registerFunctionCreator(QLatin1String("SUM"),new ConstructorGroupFunctionCreator); + m_groupFunctionFactory.registerFunctionCreator(QLatin1String("AVG"),new ConstructorGroupFunctionCreator); + m_groupFunctionFactory.registerFunctionCreator(QLatin1String("MIN"),new ConstructorGroupFunctionCreator); + m_groupFunctionFactory.registerFunctionCreator(QLatin1String("MAX"),new ConstructorGroupFunctionCreator); + + setSystemVariable(QLatin1String("#PAGE"),1,FirstPass); + setSystemVariable(QLatin1String("#PAGE_COUNT"),0,SecondPass); + + m_datasourcesModel.setDataSourceManager(this); +} +bool DataSourceManager::designTime() const +{ + return m_designTime; +} + +void DataSourceManager::setDesignTime(bool designTime) +{ + m_designTime = designTime; +} + + +DataSourceManager::~DataSourceManager() +{ + clear(All); + clearGroupFunction(); + m_instance=0; +} + +void DataSourceManager::connectAllDatabases() +{ + foreach(ConnectionDesc* conn,m_connections){ + try{ + connectConnection(conn); + } catch (ReportError e){ + putError(e.what()); + setLastError(e.what()); + qDebug()<(ds),true); + putHolder(name,holder); + emit datasourcesChanged(); + return ds; +} + +void DataSourceManager::addCallbackDatasource(ICallbackDatasource *datasource, const QString& name) +{ + IDataSource* datasourceIntf = dynamic_cast(datasource); + if (datasourceIntf){ + IDataSourceHolder* holder = new CallbackDatasourceHolder(datasourceIntf,true); + putHolder(name,holder); + emit datasourcesChanged(); + } +} + +QSharedPointerDataSourceManager::previewSQL(const QString &connectionName, const QString &sqlText) +{ + QSqlDatabase db = QSqlDatabase::database(connectionName); + if (db.isValid() && db.isOpen()){ + QSqlQueryModel* model = new QSqlQueryModel(); + model->setQuery(sqlText,db); + m_lastError = model->lastError().text(); + if (model->query().isActive()) + return QSharedPointer(model); + else + return QSharedPointer(0); + } + if (!db.isOpen()) + m_lastError = tr("Connection \"%1\" is not open").arg(connectionName); + return QSharedPointer(0); +} + +void DataSourceManager::setReportVariable(const QString &name, const QVariant &value) +{ + if (!containsVariable(name)){ + addVariable(name,value); + } else changeVariable(name,value); +} + +void DataSourceManager::addQuery(const QString &name, const QString &sqlText, const QString &connectionName) +{ + QueryDesc *queryDecs = new QueryDesc(name,sqlText,connectionName); + putQueryDesc(queryDecs); + putHolder(name,new QueryHolder(sqlText,connectionName)); + emit datasourcesChanged(); +} + +void DataSourceManager::addSubQuery(const QString &name, const QString &sqlText, const QString &connectionName, const QString &masterDatasource) +{ + SubQueryDesc *subQueryDesc = new SubQueryDesc(name.toLower(),sqlText,connectionName,masterDatasource); + putSubQueryDesc(subQueryDesc); + putHolder(name,new SubQueryHolder(sqlText,connectionName,masterDatasource)); + emit datasourcesChanged(); +} + +void DataSourceManager::addProxy(const QString &name, QString master, QString detail, QList fields) +{ + ProxyDesc *proxyDesc = new ProxyDesc(); + proxyDesc->setName(name); + proxyDesc->setMaster(master); + proxyDesc->setDetail(detail); + foreach(FieldsCorrelation correlation,fields){ + proxyDesc->addFieldsCorrelation(correlation); + } + putProxyDesc(proxyDesc); + putHolder(name,new ProxyHolder(proxyDesc)); + emit datasourcesChanged(); +} + +QString DataSourceManager::queryText(const QString &dataSourceName) +{ + if (isQuery(dataSourceName)) return queryByName(dataSourceName)->queryText(); + if (isSubQuery(dataSourceName)) return subQueryByName(dataSourceName)->queryText(); + else return QString(); +} + +QueryDesc *DataSourceManager::queryByName(const QString &dataSourceName) +{ + int queryIndex = queryIndexByName(dataSourceName); + if (queryIndex!=-1) return m_queries.at(queryIndex); + return 0; +} + +SubQueryDesc* DataSourceManager::subQueryByName(const QString &dataSourceName) +{ + int queryIndex = subQueryIndexByName(dataSourceName); + if (queryIndex!=-1) return m_subqueries.at(queryIndex); + return 0; +} + +ConnectionDesc* DataSourceManager::connectionByName(const QString &connectionName) +{ + int queryIndex = connectionIndexByName(connectionName); + if (queryIndex!=-1) return m_connections.at(queryIndex); + return 0; +} + +int DataSourceManager::queryIndexByName(const QString &dataSourceName) +{ + for(int i=0;iqueryName().compare(dataSourceName,Qt::CaseInsensitive)==0) return i; + } + return -1; +} + +int DataSourceManager::subQueryIndexByName(const QString &dataSourceName) +{ + for(int i=0;iqueryName().compare(dataSourceName,Qt::CaseInsensitive)==0) return i; + } + return -1; +} + +int DataSourceManager::proxyIndexByName(const QString &dataSourceName) +{ + for(int i=0;iname().compare(dataSourceName,Qt::CaseInsensitive)==0) return i; + } + return -1; +} + +int DataSourceManager::connectionIndexByName(const QString &connectionName) +{ + for(int i=0;iname().compare(connectionName,Qt::CaseInsensitive)==0) return i; + } + return -1; +} + +bool DataSourceManager::dataSourceIsValid(const QString &name) +{ + if (m_datasources.value(name.toLower())) return !m_datasources.value(name.toLower())->isInvalid(); + else throw ReportError(tr("Datasource \"%1\" not found !").arg(name)); +} + +bool DataSourceManager::isQuery(const QString &dataSourceName) +{ + return (queryByName(dataSourceName)); +} + +QString DataSourceManager::connectionName(const QString &dataSourceName) +{ + if (isQuery(dataSourceName)) return queryByName(dataSourceName)->connectionName(); + if (isSubQuery(dataSourceName)) return subQueryByName(dataSourceName)->connectionName(); + return QString(); +} + +ProxyDesc *DataSourceManager::proxyByName(QString datasourceName) +{ + int proxyIndex = proxyIndexByName(datasourceName); + if (proxyIndex>-1) return m_proxies.at(proxyIndex); + else return 0; +} + +void DataSourceManager::removeDatasource(const QString &name) +{ + invalidateLinkedDatasources(name); + + if (m_datasources.contains(name)){ + IDataSourceHolder *holder; + holder=m_datasources.value(name); + m_datasources.remove(name); + delete holder; + } + if (isQuery(name)){ + int queryIndex=queryIndexByName(name); + delete m_queries.at(queryIndex); + m_queries.removeAt(queryIndex); + } + if (isSubQuery(name)){ + int queryIndex=subQueryIndexByName(name); + delete m_subqueries.at(queryIndex); + m_subqueries.removeAt(queryIndex); + } + if (isProxy(name)){ + int proxyIndex=proxyIndexByName(name); + delete m_proxies.at(proxyIndex); + m_proxies.removeAt(proxyIndex); + } + emit datasourcesChanged(); +} + +void DataSourceManager::removeConnection(const QString &name) +{ + for(int i=0;iname()==name){ + QSqlDatabase db = QSqlDatabase::database(name); + db.close(); + QSqlDatabase::removeDatabase(name); + delete m_connections.at(i); + m_connections.removeAt(i); + } + } + emit datasourcesChanged(); +} + +void DataSourceManager::addConnectionDesc(ConnectionDesc * connection) +{ + if (!isConnection(connection->name())) { + connect(connection,SIGNAL(nameChanged(QString,QString)),this,SLOT(slotConnectionRenamed(QString,QString))); + m_connections.append(connection); + if (connection->autoconnect()){ + try{ + connectConnection(connection); + } catch(ReportError &exception) { + qDebug()<name())); + } +} + +void DataSourceManager::addQueryDesc(QueryDesc *query) +{ + m_queries.append(query); + addQuery(query->queryName(), query->queryText(), query->connectionName()); +} + +void DataSourceManager::putHolder(QString name, IDataSourceHolder *dataSource) +{ + if (!m_datasources.contains(name.toLower())){ + m_datasources.insert( + name.toLower(), + dataSource + ); + } else throw ReportError(tr("data source with name \"%1\" already exists !!").arg(name)); +} + +void DataSourceManager::putQueryDesc(QueryDesc* queryDesc) +{ + if (!containsDatasource(queryDesc->queryName())){ + m_queries.append(queryDesc); + } else throw ReportError(tr("datasource with name \"%1\"already exists !!").arg(queryDesc->queryName())); +} + +void DataSourceManager::putSubQueryDesc(SubQueryDesc *subQueryDesc) +{ + if (!containsDatasource(subQueryDesc->queryName())){ + m_subqueries.append(subQueryDesc); + } else throw ReportError(tr("datasource with name \"%1\" already exists !!").arg(subQueryDesc->queryName())); +} + +void DataSourceManager::putProxyDesc(ProxyDesc *proxyDesc) +{ + if (!containsDatasource(proxyDesc->name())){ + m_proxies.append(proxyDesc); + } else throw ReportError(tr("datasource with name \"%1\" already exists !!").arg(proxyDesc->name())); +} + +bool DataSourceManager::connectConnection(ConnectionDesc *connectionDesc) +{ + if (QSqlDatabase::contains(connectionDesc->name())) return QSqlDatabase::database(connectionDesc->name()).isOpen(); + + bool connected = false; + QString lastError =""; + { + QSqlDatabase db = QSqlDatabase::addDatabase(connectionDesc->driver(),connectionDesc->name()); + db.setHostName(connectionDesc->host()); + db.setUserName(connectionDesc->userName()); + db.setPassword(connectionDesc->password()); + db.setDatabaseName(connectionDesc->databaseName()); + connected=db.open(); + if (!connected) lastError=db.lastError().text(); + } + if (!connected) { + QSqlDatabase::removeDatabase(connectionDesc->name()); + setLastError(lastError); + return false; + //throw ReportError(lastError); + } else { + foreach(QString datasourceName, dataSourceNames()){ + if (isQuery(datasourceName) || isSubQuery(datasourceName)){ + QueryHolder* qh = dynamic_cast(dataSourceHolder(datasourceName)); + if (qh){ + qh->runQuery(designTime()?IDataSource::DESIGN_MODE:IDataSource::RENDER_MODE); + } + } + } + emit datasourcesChanged(); + } + return true; +} + +bool DataSourceManager::containsDatasource(const QString &dataSourceName) +{ + return m_datasources.contains(dataSourceName.toLower()); +} + +bool DataSourceManager::isSubQuery(const QString &dataSourceName) +{ + return subQueryIndexByName(dataSourceName.toLower())!=-1; +} + +bool DataSourceManager::isProxy(const QString &dataSourceName) +{ + return proxyIndexByName(dataSourceName)!=-1; +} + +bool DataSourceManager::isConnection(const QString &connectionName) +{ + return connectionIndexByName(connectionName)!=-1; +} + +bool DataSourceManager::isConnectionConnected(const QString &connectionName) +{ + if (isConnection(connectionName)){ + return QSqlDatabase::database(connectionName).isOpen(); + } + return false; +} + +bool DataSourceManager::connectConnection(const QString& connectionName) +{ + return connectConnection(connectionByName(connectionName)); +} + +void DataSourceManager::disconnectConnection(const QString& connectionName) +{ + { + QSqlDatabase db = QSqlDatabase::database(connectionName); + if (db.isOpen()) db.close(); + } + if (QSqlDatabase::contains(connectionName)) QSqlDatabase::removeDatabase(connectionName); + foreach(QString datasourceName, dataSourceNames()){ + if (isQuery(datasourceName) || isSubQuery(datasourceName)){ + QueryHolder* qh = dynamic_cast(dataSourceHolder(datasourceName)); + if (qh){ + qh->setLastError(tr("invalid connection")); + } + } + } +} + +IDataSource *DataSourceManager::dataSource(const QString &name) +{ + IDataSourceHolder* holder = m_datasources.value(name.toLower()); + if (holder) { + if (holder->isInvalid()) { + setLastError(holder->lastError()); + return 0; + } else { + return holder->dataSource(designTime()?IDataSource::DESIGN_MODE:IDataSource::RENDER_MODE); + } + } else { + setLastError(tr("Datasource \"%1\" not found !").arg(name)); + return 0; + } +} + +IDataSourceHolder *DataSourceManager::dataSourceHolder(const QString &name) +{ + if (m_datasources.value(name.toLower())) return m_datasources.value(name.toLower()); + else return 0; +} + +QStringList DataSourceManager::dataSourceNames() +{ + QStringList result; + for (int i=0;iconnectionName().compare(connectionName,Qt::CaseInsensitive)==0){ + result.append(query->queryName()); + } + } + foreach (QueryDesc* query, m_subqueries) { + if (query->connectionName().compare(connectionName,Qt::CaseInsensitive)==0){ + result.append(query->queryName()); + } + } + return result; +} + +QStringList DataSourceManager::connectionNames() +{ + QStringList result; + foreach(ConnectionDesc* conDesc,m_connections){ + result.append(conDesc->name()); + } + return result; +} + +QStringList DataSourceManager::fieldNames(const QString &datasourceName) +{ + QStringList result; + IDataSource* ds = dataSource(datasourceName); + if (ds && !ds->isInvalid()){ + for(int i=0;icolumnCount();i++){ + result.append(ds->columnNameByIndex(i)); + } + result.sort(); + } + return result; +} + +void DataSourceManager::addConnection(const QString &connectionName) +{ + addConnectionDesc(new ConnectionDesc(QSqlDatabase::database(connectionName))); + emit datasourcesChanged(); +} + +QObject *DataSourceManager::createElement(const QString& collectionName, const QString&) +{ + if (collectionName=="connections"){ + ConnectionDesc* connection = new ConnectionDesc; + m_connections.append(connection); + return connection; + } + if (collectionName=="queries"){ + QueryDesc* queryDesc = new QueryDesc; + m_queries.append(queryDesc); + return queryDesc; + } + if (collectionName=="subqueries"){ + SubQueryDesc* subQueryDesc = new SubQueryDesc; + m_subqueries.append(subQueryDesc); + return subQueryDesc; + } + if (collectionName=="subproxies"){ + ProxyDesc* proxyDesc = new ProxyDesc; + m_proxies.append(proxyDesc); + return proxyDesc; + } + + if (collectionName=="variables"){ + VarDesc* var = new VarDesc; + m_tempVars.append(var); + return var; + } + + return 0; +} + +int DataSourceManager::elementsCount(const QString &collectionName) +{ + if (collectionName=="connections"){ + return m_connections.count(); + } + if (collectionName=="queries"){ + return m_queries.count(); + } + if (collectionName=="subqueries"){ + return m_subqueries.count(); + } + if (collectionName=="subproxies"){ + return m_proxies.count(); + } + if (collectionName=="variables"){ + return m_varHolder.userVariablesCount(); + } + return 0; +} + +QObject* DataSourceManager::elementAt(const QString &collectionName, int index) +{ + if (collectionName=="connections"){ + return m_connections.at(index); + } + if (collectionName=="queries"){ + return m_queries.at(index); + } + if (collectionName=="subqueries"){ + return m_subqueries.at(index); + } + if (collectionName=="subproxies"){ + return m_proxies.at(index); + } + if (collectionName=="variables"){ + return m_varHolder.userVariableAt(index); + } + return 0; +} + +void DataSourceManager::collectionLoadFinished(const QString &collectionName) +{ + + if (collectionName.compare("connections",Qt::CaseInsensitive)==0){ + foreach(ConnectionDesc* conn,m_connections){ + if (conn->autoconnect()) { + try { + connectConnection(conn); + } catch(ReportError e){ + setLastError(e.what()); + putError(e.what()); + qDebug()<queryName(),new QueryHolder(query->queryText(),query->connectionName())); + } + } + + if (collectionName.compare("subqueries",Qt::CaseInsensitive)==0){ + foreach(SubQueryDesc* query,m_subqueries){ + putHolder(query->queryName(),new SubQueryHolder(query->queryText(),query->connectionName(),query->master())); + } + } + + if(collectionName.compare("subproxies",Qt::CaseInsensitive)==0){ + foreach(ProxyDesc* proxy,m_proxies){ + putHolder(proxy->name(),new ProxyHolder(proxy)); + } + } + + if(collectionName.compare("variables",Qt::CaseInsensitive)==0){ + foreach (VarDesc* item, m_tempVars) { + if (!m_varHolder.containsVariable(item->name())){ + m_varHolder.addVariable(item->name(),item->value(),VarDesc::User,FirstPass); + } + delete item; + } + m_tempVars.clear(); + } + + emit datasourcesChanged(); + emit loadCollectionFinished(collectionName); +} + +void DataSourceManager::addVariable(const QString &name, const QVariant &value, VarDesc::VarType type, RenderPass pass) +{ + m_varHolder.addVariable(name,value,type,pass); + if (designTime()) + emit datasourcesChanged(); +} + +void DataSourceManager::deleteVariable(const QString& name) +{ + if (m_varHolder.containsVariable(name)&&m_varHolder.variableType(name)==VarDesc::User){ + m_varHolder.deleteVariable(name); + if (designTime()) + emit datasourcesChanged(); + } +} + +void DataSourceManager::changeVariable(const QString& name,const QVariant& value) +{ + m_varHolder.changeVariable(name,value); +} + +void DataSourceManager::setSystemVariable(const QString &name, const QVariant &value, RenderPass pass) +{ + addVariable(name,value,VarDesc::System,pass); +} + +void DataSourceManager::setLastError(const QString &value){ + m_lastError = value; + if (!value.isEmpty()) { + m_errorsList.append(value); + } +} + +void DataSourceManager::invalidateLinkedDatasources(QString datasourceName) +{ + foreach(QString name, dataSourceNames()){ + if (isSubQuery(name)){ + if (subQueryByName(name)->master() == datasourceName) + dataSourceHolder(name)->invalidate(); + } + if (isProxy(name)){ + ProxyDesc* proxy = proxyByName(name); + if ((proxy->master() == datasourceName) || (proxy->child() == datasourceName)) + dataSourceHolder(name)->invalidate(); + + } + } +} + +void DataSourceManager::slotConnectionRenamed(const QString &oldName, const QString &newName) +{ + foreach(QueryDesc* query, m_queries){ + if (query->connectionName().compare(oldName,Qt::CaseInsensitive)==0) query->setConnectionName(newName); + } + foreach(SubQueryDesc* query, m_subqueries){ + if (query->connectionName().compare(oldName,Qt::CaseInsensitive)==0) query->setConnectionName(newName); + } +} + +void DataSourceManager::clear(ClearMethod method) +{ + + QList::iterator cit = m_connections.begin(); + while( cit != m_connections.end() ){ + QSqlDatabase::removeDatabase( (*cit)->name() ); + delete (*cit); + cit = m_connections.erase(cit); + } + + DataSourcesMap::iterator dit; + for( dit = m_datasources.begin(); dit != m_datasources.end(); ){ + bool owned = (*dit)->isOwned() && (*dit)->isRemovable(); + switch(method){ + case All: + invalidateLinkedDatasources(dit.key()); + delete dit.value(); + m_datasources.erase(dit++); + break; + default: + if (owned){ + invalidateLinkedDatasources(dit.key()); + delete dit.value(); + m_datasources.erase(dit++); + } else { + ++dit; + } + } + + } + + //TODO: add smart pointes to collections + foreach(QueryDesc *desc, m_queries) delete desc; + foreach(SubQueryDesc* desc, m_subqueries) delete desc; + foreach(ProxyDesc* desc, m_proxies) delete desc; + + m_queries.clear(); + m_subqueries.clear(); + m_proxies.clear(); + + emit cleared(); +} + +void DataSourceManager::clearGroupFunction() +{ + foreach(GroupFunction* gf ,m_groupFunctions.values()){ + delete gf; + } + m_groupFunctions.clear(); +} + +void DataSourceManager::clearGroupFunctionValues(const QString& bandObjectName) +{ + foreach(GroupFunction* gf, m_groupFunctions.values(bandObjectName)){ + gf->values().clear(); + } +} + +GroupFunction* DataSourceManager::addGroupFunction(const QString &name, const QString &expression, const QString &band, const QString& dataBand) +{ + GroupFunction* gf = m_groupFunctionFactory.createGroupFunction(name,expression,dataBand,this); + if (gf){ + m_groupFunctions.insert(band,gf); + } + return gf; +} + +GroupFunction *DataSourceManager::groupFunction(const QString &name, const QString &expression, const QString &band) +{ + foreach(GroupFunction* gf,m_groupFunctions.values(band)){ + if ((gf->name().compare(name,Qt::CaseInsensitive)==0)&& + (gf->data().compare(expression,Qt::CaseInsensitive)==0) + ) return gf; + } + return 0; +} + +QList DataSourceManager::groupFunctionsByBand(const QString &band) +{ + return m_groupFunctions.values(band); +} + +void DataSourceManager::updateChildrenData(const QString &datasourceName) +{ + foreach(SubQueryDesc* subquery,m_subqueries){ + if (subquery->master().compare(datasourceName,Qt::CaseInsensitive)==0){ + SubQueryHolder* holder=dynamic_cast(dataSourceHolder(subquery->queryName())); + if (holder) holder->runQuery(); + } + } + foreach(ProxyDesc* subproxy,m_proxies){ + if(subproxy->master().compare(datasourceName,Qt::CaseInsensitive)==0){ + ProxyHolder* holder = dynamic_cast(dataSourceHolder(subproxy->name())); + holder->filterModel(); + } + } +} + +QString DataSourceManager::extractDataSource(const QString &fieldName) +{ + return fieldName.left(fieldName.indexOf('.')); +} + +QString DataSourceManager::extractFieldName(const QString &fieldName) +{ + return fieldName.right((fieldName.length()-fieldName.indexOf('.'))-1); +} + +bool DataSourceManager::containsField(const QString &fieldName) +{ + IDataSource* ds = dataSource(extractDataSource(fieldName)); + if (ds) { + return ds->columnIndexByName(extractFieldName(fieldName))!=-1; + } + return false; +} + +bool DataSourceManager::containsVariable(const QString& variableName) +{ + return m_varHolder.containsVariable(variableName); +} + +void DataSourceManager::clearUserVariables() +{ + m_varHolder.clearUserVariables(); +} + +QVariant DataSourceManager::fieldData(const QString &fieldName) +{ + if (containsField(fieldName)){ + IDataSource* ds = dataSource(extractDataSource(fieldName)); + if (ds) return ds->data(extractFieldName(fieldName)); + } + return QVariant(); +} + +QVariant DataSourceManager::variable(const QString &variableName) +{ + return m_varHolder.variable(variableName); +} + +RenderPass DataSourceManager::variablePass(const QString &name) +{ + + return (m_varHolder.variablePass(name)==FirstPass)?FirstPass:SecondPass; +} + +bool DataSourceManager::variableIsSystem(const QString &name) +{ + return (m_varHolder.variableType(name)==VarDesc::System); +} + +QStringList DataSourceManager::variableNames() +{ + return m_varHolder.variableNames(); +} + +VarDesc::VarType DataSourceManager::variableType(const QString &name) +{ + return m_varHolder.variableType(name); +} + +void DataSourceManager::setAllDatasourcesToFirst() +{ + foreach(IDataSourceHolder* ds,m_datasources.values()) { + if (ds->dataSource()) ds->dataSource()->first(); + } +} + +} //namespace LimeReport diff --git a/src/lrdatasourcemanager.h b/src/lrdatasourcemanager.h new file mode 100644 index 0000000..5b11b05 --- /dev/null +++ b/src/lrdatasourcemanager.h @@ -0,0 +1,229 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRDATASOURCEMANAGER_H +#define LRDATASOURCEMANAGER_H + +#include +#include +#include "lrdatasourcemanager.h" +#include "lrdatadesignintf.h" +#include "lrcollection.h" +#include "lrglobal.h" +#include "lrvariablesholder.h" +#include "lrgroupfunctions.h" +#include "lrdatasourcemanagerintf.h" + +namespace LimeReport{ + + +class DataSourceManager; + +class DataNode { +public: + enum NodeType{Root,Connection,DataSources,Query,SubQuery,Model,Field,Variables,Variable}; + DataNode(const QString& name="", NodeType type=Root, DataNode* parent=0, const QIcon& icon=QIcon()) + :m_name(name), m_icon(icon), m_type(type), m_parent(parent){} + virtual ~DataNode(); + int childCount(){return m_childs.count();} + DataNode* child(int index){return m_childs[index];} + DataNode* parent(){return m_parent;} + DataNode* addChild(const QString& name="", NodeType type=Root, const QIcon& icon=QIcon()); + int row(); + QString name(){return m_name;} + QIcon icon(){return m_icon;} + void clear(); + NodeType type(){return m_type;} +private: + QString m_name; + QIcon m_icon; + NodeType m_type; + DataNode* m_parent; + QVector m_childs; +}; + +class DataSourceModel : public QAbstractItemModel{ + Q_OBJECT +public: + DataSourceModel():m_rootNode(new DataNode()){} + DataSourceModel(DataSourceManager* dataManager); + QModelIndex index(int row, int column, const QModelIndex &parent) const; + ~DataSourceModel(); + QModelIndex parent(const QModelIndex &child) const; + int rowCount(const QModelIndex &parent) const; + int columnCount(const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role) const; + void setDataSourceManager(DataSourceManager* dataManager); +private slots: + void slotDatasourcesChanged(); +private: + DataNode* nodeFromIndex(const QModelIndex &index) const; + void fillFields(DataNode* parent); + void updateModel(); +private: + DataSourceManager* m_dataManager; + DataNode* m_rootNode; +}; + +class DataSourceManager : public QObject, public ICollectionContainer, public IVariablesContainer, public IDataSourceManager +{ + Q_OBJECT + Q_PROPERTY(ACollectionProperty connections READ fakeCollectionReader) + Q_PROPERTY(ACollectionProperty queries READ fakeCollectionReader) + Q_PROPERTY(ACollectionProperty subqueries READ fakeCollectionReader) + Q_PROPERTY(ACollectionProperty subproxies READ fakeCollectionReader) + Q_PROPERTY(ACollectionProperty variables READ fakeCollectionReader) + friend class ReportEnginePrivate; + friend class ReportRender; +public: + static DataSourceManager* instance(){return m_instance;} +public: + typedef QHash DataSourcesMap; + enum ClearMethod {All,Owned}; + ~DataSourceManager(); + void connectAllDatabases(); + void addConnection(const QString& connectionName); + void addConnectionDesc(ConnectionDesc *); + void addQuery(const QString& name, const QString& sqlText, const QString& connectionName=""); + void addSubQuery(const QString& name, const QString& sqlText, const QString& connectionName, const QString& masterDatasource); + void addProxy(const QString& name, QString master, QString detail, QList fields); + void addModel(const QString& name, QAbstractItemModel *model, bool owned); + ICallbackDatasource* createCallbackDatasouce(const QString &name); + void addCallbackDatasource(ICallbackDatasource *datasource, const QString &name); + void setReportVariable(const QString& name, const QVariant& value); + void deleteVariable(const QString& name); + bool containsVariable(const QString& variableName); + void clearUserVariables(); + QVariant variable(const QString& variableName); + RenderPass variablePass(const QString& name); + QStringList variableNames(); + VarDesc::VarType variableType(const QString& name); + + bool variableIsSystem(const QString& name); + QString queryText(const QString& dataSourceName); + QString connectionName(const QString& dataSourceName); + void removeDatasource(const QString& name); + void removeConnection(const QString& name); + bool isQuery(const QString& dataSourceName); + bool containsDatasource(const QString& dataSourceName); + bool isSubQuery(const QString& dataSourceName); + bool isProxy(const QString& dataSourceName); + bool isConnection(const QString& connectionName); + bool isConnectionConnected(const QString& connectionName); + bool connectConnection(const QString &connectionName); + void disconnectConnection(const QString &connectionName); + QueryDesc* queryByName(const QString& dataSourceName); + SubQueryDesc* subQueryByName(const QString& dataSourceName); + ProxyDesc* proxyByName(QString datasourceName); + ConnectionDesc *connectionByName(const QString& connectionName); + int queryIndexByName(const QString& dataSourceName); + int subQueryIndexByName(const QString& dataSourceName); + int proxyIndexByName(const QString& dataSourceName); + int connectionIndexByName(const QString& connectionName); + + bool dataSourceIsValid(const QString& name); + IDataSource* dataSource(const QString& name); + IDataSourceHolder* dataSourceHolder(const QString& name); + QStringList dataSourceNames(); + QStringList dataSourceNames(const QString& connectionName); + QStringList connectionNames(); + QStringList fieldNames(const QString& datasourceName); + bool containsField(const QString& fieldName); + QVariant fieldData(const QString& fieldName); + + QString extractDataSource(const QString& fieldName); + QString extractFieldName(const QString& fieldName); + void setAllDatasourcesToFirst(); + void clear(ClearMethod method); + void clearGroupFunction(); + void clearGroupFunctionValues(const QString &bandObjectName); + + QList groupFunctionNames(){return m_groupFunctionFactory.functionNames();} + GroupFunction* addGroupFunction(const QString& name, const QString& expression, const QString& band, const QString &dataBand); + GroupFunction* groupFunction(const QString& name, const QString &expression, const QString& band); + QList groupFunctionsByBand(const QString& band); + void updateChildrenData(const QString& datasourceName); + + DataSourceModel* datasourcesModel(){return &m_datasourcesModel;} + QString lastError() const { return m_lastError;} + + void putError(QString error){ if (!m_errorsList.contains(error)) m_errorsList.append(error);} + void clearErrorsList(){ m_errorsList.clear();} + QStringList errorsList(){ return m_errorsList;} + bool designTime() const; + void setDesignTime(bool designTime); + QSharedPointer previewSQL(const QString& connectionName, const QString& sqlText); + +signals: + void loadCollectionFinished(const QString& collectionName); + void cleared(); + void datasourcesChanged(); +protected: + void addQueryDesc(QueryDesc *); + void putHolder(QString name, LimeReport::IDataSourceHolder* dataSource); + void putQueryDesc(QueryDesc *queryDesc); + void putSubQueryDesc(SubQueryDesc *subQueryDesc); + void putProxyDesc(ProxyDesc *proxyDesc); + bool connectConnection(ConnectionDesc* connectionDesc); + //ICollectionContainer + virtual QObject* createElement(const QString& collectionName,const QString&); + virtual int elementsCount(const QString& collectionName); + virtual QObject *elementAt(const QString& collectionName,int index); + virtual void collectionLoadFinished(const QString& collectionName); + + void addVariable(const QString& name, const QVariant& value, VarDesc::VarType type=VarDesc::User, RenderPass pass=FirstPass); + void changeVariable(const QString& name,const QVariant& value); + void setSystemVariable(const QString& name, const QVariant& value, RenderPass pass); + void setLastError(const QString& value); + void invalidateLinkedDatasources(QString datasourceName); +private slots: + void slotConnectionRenamed(const QString& oldName,const QString& newName); +private: + explicit DataSourceManager(QObject *parent = 0); + Q_DISABLE_COPY(DataSourceManager) +private: + static DataSourceManager* m_instance; + QList m_connections; + QList m_queries; + QList m_subqueries; + QList m_proxies; + QList m_tempVars; + + QMultiMap m_groupFunctions; + GroupFunctionFactory m_groupFunctionFactory; + AVariablesHolder m_varHolder; + DataSourcesMap m_datasources; + DataSourceModel m_datasourcesModel; + QString m_lastError; + QStringList m_errorsList; + bool m_designTime; +}; + +} +#endif // LRDATASOURCEMANAGER_H diff --git a/src/lrdatasourcemanagerintf.h b/src/lrdatasourcemanagerintf.h new file mode 100644 index 0000000..123f049 --- /dev/null +++ b/src/lrdatasourcemanagerintf.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRDATASOURCEMANAGERINTF_H +#define LRDATASOURCEMANAGERINTF_H + +#include "lrcallbackdatasourceintf.h" + +class QVariant; +class QString; +class QAbstractItemModel; +namespace LimeReport{ + +class IDataSourceManager{ +public: + virtual void setReportVariable(const QString& name, const QVariant& value)=0; + virtual void deleteVariable(const QString& name)=0; + virtual bool containsVariable(const QString& variableName)=0; + virtual QVariant variable(const QString& variableName)=0; + virtual void addModel(const QString& name, QAbstractItemModel *model, bool owned)=0; + virtual bool containsDatasource(const QString& dataSourceName)=0; + virtual void clearUserVariables()=0; + virtual ICallbackDatasource* createCallbackDatasouce(const QString& name) = 0; + virtual void addCallbackDatasource(ICallbackDatasource* datasource, const QString& name) = 0; +}; + +} +#endif // LRDATASOURCEMANAGERINTF_H diff --git a/src/lrdesignelementsfactory.h b/src/lrdesignelementsfactory.h new file mode 100644 index 0000000..3afc554 --- /dev/null +++ b/src/lrdesignelementsfactory.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRDESIGNELEMENTSFACTORY_H +#define LRDESIGNELEMENTSFACTORY_H + +#include "lrbanddesignintf.h" +#include "lrpageheader.h" +#include "lrattribsabstractfactory.h" +#include "lrsimpleabstractfactory.h" +#include "lrsingleton.h" + +namespace LimeReport{ + +typedef BaseDesignIntf* (*CreateBand)(QObject* owner, BaseDesignIntf* parent); + +struct ItemAttribs{ + QString m_alias; + QString m_tag; + ItemAttribs(){} + ItemAttribs(const QString& alias, const QString& tag):m_alias(alias),m_tag(tag){} + bool operator==( const ItemAttribs &right) const { + return (m_alias==right.m_alias) && (m_tag==right.m_tag); + } +}; + +class DesignElementsFactory : public AttribsAbstractFactory +{ +private: + friend class Singleton; +private: + DesignElementsFactory(){} + ~DesignElementsFactory(){} + DesignElementsFactory(const DesignElementsFactory&){} + DesignElementsFactory& operator = (const DesignElementsFactory&){return *this;} +}; + +} +#endif // LRDESIGNELEMENTSFACTORY_H diff --git a/src/lrglobal.cpp b/src/lrglobal.cpp new file mode 100644 index 0000000..34bd880 --- /dev/null +++ b/src/lrglobal.cpp @@ -0,0 +1,40 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include +#include +#include "lrglobal.h" + +QString LimeReport::extractClassName(QString className) +{ + int startPos=className.lastIndexOf("::"); + if(startPos==-1) startPos=0; + else startPos+=2; + return className.right(className.length()-startPos); +} diff --git a/src/lrglobal.h b/src/lrglobal.h new file mode 100644 index 0000000..a701619 --- /dev/null +++ b/src/lrglobal.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef GLOBAL_H +#define GLOBAL_H +#include "qglobal.h" +#include +#include + +#if defined(LIMEREPORT_EXPORTS) +# define LIMEREPORT_EXPORT Q_DECL_EXPORT +#elif defined (LIMEREPORT_IMPORTS) +# define LIMEREPORT_EXPORT Q_DECL_IMPORT +#else +# define LIMEREPORT_EXPORT /**/ +#endif + +namespace LimeReport { + const qreal fontFACTOR = 3.5; + const int mmFACTOR = 10; + const int itemPaleteIconSize = 24; + const qreal minSpaceBorder = 10; + QString extractClassName(QString className); + const QString bandTAG = "band"; + const qreal BAND_MARKER_OPACITY = 1; + const qreal LAYOUT_MARKER_OPACITY = 0.3; + const qreal BAND_NAME_AREA_OPACITY = 0.3; + const qreal BAND_NAME_TEXT_OPACITY = 0.6; + const qreal SELECTION_OPACITY = 0.3; + enum RenderPass {FirstPass, SecondPass}; + enum ArrangeType {AsNeeded, Force}; + const QString FIELD_RX = "\\$D\\s*\\{\\s*([^\\s{}]*)\\s*\\}"; + const QString VARIABLE_RX = "\\$V\\s*\\{\\s*([^\\s{}]*)\\s*\\}"; + const QString SCRIPT_RX = "\\$S\\s*\\{(.*)\\}"; + const QString GROUP_FUNCTION_PARAM_RX = "\\(\\s*(((?:\\\"?\\$D\\s*\\{\\s*)|(?:\\\"?\\$V\\s*\\{\\s*)|(?:\\\"))(\\w+\\.?\\w+)((?:\\\")|(?:\\s*\\}\\\"?\\s*)))\\s*,\\s*\\\"(\\w+)\\\"\\s*\\)"; + const int DATASOURCE_INDEX = 6; + const int VALUE_INDEX = 2; + const QString GROUP_FUNCTION_RX = "(%1\\s*"+GROUP_FUNCTION_PARAM_RX+")"; + const QString GROUP_FUNCTION_NAME_RX = "%1\\s*\\((.*[^\\)])\\)"; + const int SCENE_MARGIN = 50; + class ReportError : public std::runtime_error{ + public: + ReportError(const QString& message):std::runtime_error(message.toStdString()){} + }; + +} // namespace LimeReport + + + +#endif // GLOBAL_H diff --git a/src/lrgroupfunctions.cpp b/src/lrgroupfunctions.cpp new file mode 100644 index 0000000..1f2ab18 --- /dev/null +++ b/src/lrgroupfunctions.cpp @@ -0,0 +1,173 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrgroupfunctions.h" +#include "lrdatasourcemanager.h" +#include "lrbanddesignintf.h" +#include "lritemdesignintf.h" + +#include + +namespace LimeReport { + +void GroupFunction::slotBandRendered(BandDesignIntf *band) +{ + switch (m_dataType){ + case Field: + if (m_dataManager->containsField(m_data)){ + m_values.push_back(m_dataManager->fieldData(m_data)); + } else { + setInvalid(tr("Field \"%1\" not found").arg(m_data)); + } + break; + case Variable: + if (m_dataManager->containsVariable(m_data)){ + m_values.push_back(m_dataManager->variable(m_data)); + } else { + setInvalid(tr("Variable \"%1\" not found").arg(m_data)); + } + break; + case ContentItem:{ + ContentItemDesignIntf* item = dynamic_cast(band->childByName(m_data)); + if (item) + m_values.push_back(item->content()); + else setInvalid(tr("Item \"%1\" not found").arg(m_data)); + break; + } + default: + break; + } +} + +QVariant GroupFunction::addition(QVariant value1, QVariant value2) +{ + return value1.toDouble()+value2.toDouble(); +} + +QVariant GroupFunction::subtraction(QVariant value1, QVariant value2) +{ + return value1.toDouble()-value2.toDouble(); +} + +QVariant GroupFunction::division(QVariant value1, QVariant value2) +{ + return value1.toDouble() / value2.toDouble(); +} + +QVariant GroupFunction::multiplication(QVariant value1, QVariant value2) +{ + return value1.toDouble() * value2.toDouble(); +} + +GroupFunction::GroupFunction(const QString &expression, const QString &dataBandName, DataSourceManager* dataManager) + :m_dataBandName(dataBandName), m_dataManager(dataManager),m_isValid(true), m_errorMessage("") +{ + QRegExp rxField(FIELD_RX,Qt::CaseInsensitive); + if (rxField.indexIn(expression)>=0){ + m_dataType=Field; + m_data = rxField.cap(1); + return; + } + + QRegExp rxVariable(VARIABLE_RX,Qt::CaseInsensitive); + if (rxVariable.indexIn(expression)>=0){ + m_dataType=Variable; + m_data = rxVariable.cap(1); + return; + } + + m_dataType = ContentItem; + m_data = expression; + m_data = m_data.remove('"'); + +} + +GroupFunction *GroupFunctionFactory::createGroupFunction(const QString &functionName, const QString &expression, const QString& dataBandName, DataSourceManager *dataManager) +{ + if (m_creators.contains(functionName)){ + return m_creators.value(functionName)->createFunction(expression, dataBandName, dataManager); + } + return 0; +} + +GroupFunctionFactory::~GroupFunctionFactory() +{ + foreach(GroupFunctionCreator* creator, m_creators.values()){ + delete creator; + } + m_creators.clear(); +} + +QVariant SumGroupFunction::calculate() +{ + QVariant res=0; + foreach(QVariant value,values()){ + res=addition(res,value); + } + return res; +} + +QVariant AvgGroupFunction::calculate() +{ + QVariant res=QVariant(); + foreach(QVariant value,values()){ + res=addition(res,value); + } + if (!res.isNull()&&(values().count()>0)){ + res=division(res,values().count()); + } + return res; +} + +QVariant MinGroupFunction::calculate() +{ + //TODO: check variant type + QVariant res = QVariant(); + if (!values().empty()) res = values().at(0); + foreach(QVariant value, values()){ + if (res.toDouble()>value.toDouble()) res = value; + } + + return res; +} + +QVariant MaxGroupFunction::calculate() +{ + //TODO: check variant type + QVariant res = QVariant(); + if (!values().empty()) res = values().at(0); + foreach(QVariant value, values()){ + if (res.toDouble(). * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRGROUPFUNCTIONS_H +#define LRGROUPFUNCTIONS_H + +#include +#include +#include + +namespace LimeReport{ + +class DataSourceManager; +class BandDesignIntf; + +class GroupFunction : public QObject{ + Q_OBJECT +public: + enum DataType{Variable,Field,Srcipt,ContentItem}; + GroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager); + bool isValid(){return m_isValid;} + void setInvalid(QString message){m_isValid=false,m_errorMessage=message;} + const QString& name(){return m_name;} + const QString& data(){return m_data;} + const QString& error(){return m_errorMessage;} + QVector& values(){return m_values;} + const QString& dataBandName(){return m_dataBandName;} + virtual QVariant calculate()=0; +public slots: + void slotBandRendered(BandDesignIntf* band); +protected: + void setName(const QString& value){m_name=value;} + QVariant addition(QVariant value1, QVariant value2); + QVariant subtraction(QVariant value1, QVariant value2); + QVariant division(QVariant value1, QVariant value2); + QVariant multiplication(QVariant value1, QVariant value2); +private: + QString m_data; + QString m_name; + DataType m_dataType; + QString m_dataBandName; + QVector m_values; + DataSourceManager* m_dataManager; + bool m_isValid; + QString m_errorMessage; +}; + +class GroupFunctionCreator{ +public: + virtual GroupFunction* createFunction(const QString&, const QString&, DataSourceManager*)=0; + virtual ~GroupFunctionCreator(){} +}; + +class GroupFunctionFactory{ +public: + void registerFunctionCreator(const QString& functionName,GroupFunctionCreator* creator){ + m_creators.insert(functionName,creator); + } + QList functionNames(){return m_creators.keys();} + GroupFunction* createGroupFunction(const QString& functionName, const QString& expression, const QString& dataBandName, DataSourceManager* dataManager); + ~GroupFunctionFactory(); +private: + QMap m_creators; +}; + +class CountGroupFunction :public GroupFunction{ + Q_OBJECT +public: + CountGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager) + :GroupFunction(expression, dataBandName, dataManager){setName("COUNT");} +protected: + virtual QVariant calculate(){return values().count();} +}; + +class SumGroupFunction :public GroupFunction{ + Q_OBJECT +public: + SumGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager) + :GroupFunction(expression, dataBandName, dataManager){setName("SUM");} +protected: + virtual QVariant calculate(); +}; + +class AvgGroupFunction :public GroupFunction{ + Q_OBJECT +public: + AvgGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager) + :GroupFunction(expression, dataBandName, dataManager){setName("AVG");} +protected: + virtual QVariant calculate(); +}; + +class MinGroupFunction :public GroupFunction{ + Q_OBJECT +public: + MinGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager) + :GroupFunction(expression, dataBandName, dataManager){setName("MIN");} +protected: + virtual QVariant calculate(); +}; + +class MaxGroupFunction :public GroupFunction{ + Q_OBJECT +public: + MaxGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager) + :GroupFunction(expression, dataBandName, dataManager){setName("MAX");} +protected: + virtual QVariant calculate(); +}; + +template +class ConstructorGroupFunctionCreator : public GroupFunctionCreator{ + virtual GroupFunction* createFunction(const QString& expression, const QString &dataBandName, DataSourceManager* dataManager); +}; + +template< typename T > +GroupFunction* ConstructorGroupFunctionCreator< T >::createFunction(const QString &expression, const QString &dataBandName, DataSourceManager *dataManager) +{ + return new T(expression, dataBandName, dataManager); +} + +} //namespace LimeReport + +#endif // LRGROUPFUNCTIONS_H diff --git a/src/lritemdesignintf.cpp b/src/lritemdesignintf.cpp new file mode 100644 index 0000000..0ce0542 --- /dev/null +++ b/src/lritemdesignintf.cpp @@ -0,0 +1,239 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lritemdesignintf.h" +#include "lrbasedesignintf.h" +#include "lrpagedesignintf.h" +#include "lrdatasourcemanager.h" +#include "lrscriptenginemanager.h" +#include "lrglobal.h" + +#include +#include +#include + +namespace LimeReport{ + +ItemDesignIntf::ItemDesignIntf(const QString &xmlTypeName, QObject* owner, QGraphicsItem* parent) : + BaseDesignIntf(xmlTypeName,owner,parent), m_itemLocation(Band), m_stretchToMaxHeight(false){ + initFlags(); +} + +void ItemDesignIntf::setItemLocation(LocationType location) +{ + + if (m_itemLocation!=location){ + LocationType oldValue = m_itemLocation; + m_itemLocation=location; + if(!isLoading()){ + if (location==Band){ + QGraphicsItem *parentBand=bandByPos(); + if (parentBand){ + QPointF parentPos = parentBand->mapFromItem(parentItem(),x(),y()); + setParentItem(parentBand); + setParent(dynamic_cast(parentBand)); + setPos(parentPos); + } else { + m_itemLocation=Page; + } + } else { + if (scene()){ + PageItemDesignIntf* page = dynamic_cast(scene())->pageItem(); + QPointF parentPos = page->mapFromItem(parentItem(),x(),y()); + setParentItem(page); + setParent(page); + setPos(parentPos); + } + } + notify("locationType",oldValue,location); + } + } +} + +void ItemDesignIntf::setStretchToMaxHeight(bool value) +{ + if (m_stretchToMaxHeight!=value){ + bool oldValue = m_stretchToMaxHeight; + m_stretchToMaxHeight=value; + notify("stretchToMaxHeight",oldValue,value); + } +} + +BaseDesignIntf *ItemDesignIntf::cloneEmpty(int height, QObject *owner, QGraphicsItem *parent) +{ + BaseDesignIntf* spacer = new Spacer(owner,parent); + spacer->initFromItem(this); + spacer->setHeight(height); + return spacer; +} + +QGraphicsItem * ItemDesignIntf::bandByPos() +{ + foreach(QGraphicsItem *item,collidingItems()){ + if (dynamic_cast(item)){ + return item; + } + } + return 0; +} + +void ItemDesignIntf::initFlags() +{ + BaseDesignIntf::initFlags(); + if ((itemMode()&DesignMode) || (itemMode()&EditMode)){ + setFlag(QGraphicsItem::ItemIsMovable); + } else { + setFlag(QGraphicsItem::ItemIsMovable,false); + } +} + +QString ContentItemDesignIntf::expandDataFields(QString context, ExpandType expandType) +{ + DataSourceManager* dm = DataSourceManager::instance(); + QRegExp rx(FIELD_RX); + + if (context.contains(rx)){ + while ((rx.indexIn(context))!=-1){ + QString field=rx.cap(1); + + if (dm->containsField(field)) { + QString fieldValue; + if (expandType == EscapeSymbols) { + if (dm->fieldData(field).isNull()) { + fieldValue="\"\""; + } else { + fieldValue = escapeSimbols(dm->fieldData(field).toString()); + switch (dm->fieldData(field).type()) { + case QVariant::Char: + case QVariant::String: + case QVariant::StringList: + case QVariant::Date: + case QVariant::DateTime: + fieldValue = "\""+fieldValue+"\""; + break; + default: + break; + } + } + } else { + fieldValue = dm->fieldData(field).toString(); + } + + context.replace(rx.cap(0),fieldValue); + + } else { + QString error; + if (dm->lastError().isEmpty()){ + error = QString("Field %1 not found in %2 !!! ").arg(field).arg(this->objectName()); + dm->putError(error); + } else { + error = dm->lastError(); + } + context.replace(rx.cap(0),error); + } + } + } + + return context; +} + +QString ContentItemDesignIntf::expandUserVariables(QString context, RenderPass pass, ExpandType expandType) +{ + DataSourceManager* dm=DataSourceManager::instance(); + //QRegExp rx("\\$V\\{([^{}]*)\\}"); + QRegExp rx(VARIABLE_RX); + if (context.contains(rx)){ + int pos = 0; + while ((pos = rx.indexIn(context,pos))!=-1){ + QString variable=rx.cap(1); + pos += rx.matchedLength(); + if (dm->containsVariable(variable) ){ + if (pass==dm->variablePass(variable)){ + if (expandType==EscapeSymbols){ + context.replace(rx.cap(0),escapeSimbols(dm->variable(variable).toString())); + } else { + context.replace(rx.cap(0),dm->variable(variable).toString()); + } + pos=0; + } + } else { + context.replace(rx.cap(0),tr("Variable %1 not found").arg(variable)); + } + } + } + return context; +} + +QString ContentItemDesignIntf::expandScripts(QString context) +{ + QRegExp rx(SCRIPT_RX); + + if (context.contains(rx)){ + QScriptEngine* se = ScriptEngineManager::instance().scriptEngine(); + + QScriptValue svThis = se->globalObject().property("THIS"); + if (svThis.isValid()){ + se->newQObject(svThis, this); + } else { + svThis = se->newQObject(this); + se->globalObject().setProperty("THIS",svThis); + } + + ScriptExtractor scriptExtractor(context); + if (scriptExtractor.parse()){ + for(int i=0; ievaluate(scriptBody); + if (!se->hasUncaughtException()) { + context.replace(scriptExtractor.scriptAt(i),value.toString()); + } else { + context.replace(scriptExtractor.scriptAt(i),se->uncaughtException().toString()); + } + } + } + } + return context; +} + +QString ContentItemDesignIntf::content() const +{ + return ""; +} + +QString ContentItemDesignIntf::escapeSimbols(const QString &value) +{ + QString result = value; + return result.replace("\"","\\\""); +} + +Spacer::Spacer(QObject *owner, QGraphicsItem *parent) + :ItemDesignIntf("Spacer",owner,parent){} + +}// namespace LimeReport diff --git a/src/lritemdesignintf.h b/src/lritemdesignintf.h new file mode 100644 index 0000000..ca2b926 --- /dev/null +++ b/src/lritemdesignintf.h @@ -0,0 +1,97 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRITEMDESIGNITTF_H +#define LRITEMDESIGNITTF_H + +#include +#include "lrbasedesignintf.h" + +namespace LimeReport{ +class BaseDesignIntf; +class ItemDesignIntf : public BaseDesignIntf +{ + Q_OBJECT + Q_PROPERTY(LocationType itemLocation READ itemLocation WRITE setItemLocation) + Q_PROPERTY(bool stretchToMaxHeight READ stretchToMaxHeight WRITE setStretchToMaxHeight) + Q_ENUMS(LocationType) +public: + enum LocationType{Band,Page}; + ItemDesignIntf(const QString& xmlTypeName, QObject* owner = 0,QGraphicsItem* parent = 0); + LocationType itemLocation(){return m_itemLocation;} + void setItemLocation(LocationType location); + void setStretchToMaxHeight(bool value); + bool stretchToMaxHeight(){return m_stretchToMaxHeight;} + BaseDesignIntf* cloneEmpty(int height, QObject *owner, QGraphicsItem *parent); +protected: + QGraphicsItem* bandByPos(); + virtual void initFlags(); +private: + LocationType m_itemLocation; + bool m_stretchToMaxHeight; +}; + +class Spacer :public ItemDesignIntf{ +public: + Spacer(QObject* owner,QGraphicsItem* parent); +protected: + BaseDesignIntf* createSameTypeItem(QObject *owner, QGraphicsItem *parent){ + return new Spacer(owner, parent); + } +}; + +class ContentItemDesignIntf : public ItemDesignIntf +{ + Q_OBJECT +public: + ContentItemDesignIntf(const QString& xmlTypeName, QObject* owner = 0,QGraphicsItem* parent = 0) + :ItemDesignIntf(xmlTypeName,owner,parent){} + virtual QString content() const; + virtual void setContent(const QString& value)=0; + enum ExpandType {EscapeSymbols, NoEscapeSymbols}; +protected: + QString escapeSimbols(const QString& value); + virtual QString expandUserVariables(QString context, RenderPass pass, ExpandType expandType); + virtual QString expandDataFields(QString context, ExpandType expandType); + virtual QString expandScripts(QString context); + +}; + +class LayoutDesignIntf : public ItemDesignIntf{ +public: + LayoutDesignIntf(const QString& xmlTypeName, QObject* owner = 0,QGraphicsItem* parent = 0): + ItemDesignIntf(xmlTypeName,owner,parent){} + virtual void addChild(BaseDesignIntf *item,bool updateSize=true) = 0; + virtual void restoreChild(BaseDesignIntf *item) = 0; + virtual int childrenCount() = 0; + friend class BaseDesignIntf; +}; + +} +#endif // LRITEMDESIGNITTF_H diff --git a/src/lrpagedesignintf.cpp b/src/lrpagedesignintf.cpp new file mode 100644 index 0000000..5f5dd9d --- /dev/null +++ b/src/lrpagedesignintf.cpp @@ -0,0 +1,1816 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrpagedesignintf.h" +#include "lrbasedesignintf.h" +#include "lrtextitem.h" +#include "lrhorizontallayout.h" +//#include "lrbarcodeitem.h" +#include "lrbanddesignintf.h" +#include "lrbandsmanager.h" +#include "lrreportengine_p.h" + +#include "serializators/lrstorageintf.h" +#include "serializators/lrxmlwriter.h" +#include "serializators/lrxmlreader.h" +#include "lrdesignelementsfactory.h" + +#include "lrpageheader.h" +#include "lrpagefooter.h" + +#include "lrglobal.h" + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace LimeReport +{ + +bool bandSortBandLessThen(const BandDesignIntf *c1, const BandDesignIntf *c2) +{ + return c1->geometry().top() < c2->geometry().top(); +} + +PageDesignIntf::PageDesignIntf(QObject *parent): + QGraphicsScene(parent), + m_pageSize(A4), + m_orientation(Portrait), + m_pageItem(0), + m_insertMode(false), + m_itemInsertRect(0), + m_itemMode(DesignMode), + m_cutterBorder(0), + m_currentCommand(-1), + m_changeSizeMode(false), + m_changePosMode(false), + m_changePosOrSizeMode(false), + m_executingCommand(false), + m_hasHanges(false), + m_isLoading(false), + m_executingGroupCommand(false), + m_settings(0), + m_selectionRect(0) +{ + m_reportEditor = dynamic_cast(parent); + updatePageRect(); + connect(this, SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged())); + setBackgroundBrush(QBrush(Qt::white)); +} + +PageDesignIntf::~PageDesignIntf() +{ + if (!m_pageItem.isNull()) { + removeItem(m_pageItem.data()); + m_pageItem.clear(); + } + foreach (PageItemDesignIntf::Ptr pageItem, m_reportPages) { + removeItem(pageItem.data()); + } + m_commandsList.clear(); +} + +void PageDesignIntf::updatePageRect() +{ + if (m_pageItem.isNull()) { + m_pageItem = PageItemDesignIntf::create(this); + addItem(m_pageItem.data()); + m_pageItem->setTopMargin(5); + m_pageItem->setBottomMargin(5); + m_pageItem->setLeftMargin(5); + m_pageItem->setRightMargin(5); + m_pageItem->setObjectName("ReportPage1"); + connect(m_pageItem.data(), SIGNAL(itemSelected(LimeReport::BaseDesignIntf *)), this, SIGNAL(itemSelected(LimeReport::BaseDesignIntf *))); + connect(m_pageItem.data(), SIGNAL(geometryChanged(QObject *, QRectF, QRectF)), this, SLOT(slotPageGeomertyChanged(QObject *, QRectF, QRectF))); + connect(m_pageItem.data(), SIGNAL(objectLoaded(QObject *)), this, SLOT(slotPageItemLoaded(QObject *))); + } + this->setSceneRect(-SCENE_MARGIN, -SCENE_MARGIN, + pageItem()->geometry().width() + SCENE_MARGIN*2, + pageItem()->geometry().height() + SCENE_MARGIN*2); + emit sceneRectChanged(sceneRect()); +} + +PageDesignIntf::Orientation PageDesignIntf::getOrientation() +{ + return m_orientation; +} + +void PageDesignIntf::setPageSize(PageDesignIntf::PageSize sizeType, QSizeF sizeValue) +{ + m_pageSize = sizeType; + m_pageSizeValue = sizeValue; + updatePageRect(); +} + +PageDesignIntf::PageSize PageDesignIntf::pageSize() const +{ + return m_pageSize; +} + +void PageDesignIntf::keyPressEvent(QKeyEvent *event) +{ + if (event->modifiers() == Qt::NoModifier || + (event->key() != Qt::Key_Left && + event->key() != Qt::Key_Right && + event->key() != Qt::Key_Up && + event->key() != Qt::Key_Down && + !m_changePosMode && !m_changeSizeMode ) + ) { + QGraphicsScene::keyPressEvent(event); + return; + } + + if ((event->modifiers()& Qt::ControlModifier) && (!m_changeSizeMode)) { + if (!m_changePosMode) { + saveSelectedItemsPos(); + m_changePosMode = true; + } + } + + if ((event->modifiers()& Qt::ShiftModifier) && (!m_changePosMode)) { + if (!m_changeSizeMode) { + saveSelectedItemsGeometry(); + m_changeSizeMode = true; + } + } + + if ((event->modifiers()& Qt::ControlModifier) && m_changePosMode && (!(event->modifiers()& Qt::ShiftModifier))) { + foreach(QGraphicsItem * item, selectedItems()) { + if (dynamic_cast(item)) { + switch (event->key()) { + case Qt::Key_Right: + dynamic_cast(item)->moveRight(); + break; + case Qt::Key_Left: + dynamic_cast(item)->moveLeft(); + break; + case Qt::Key_Up: + dynamic_cast(item)->moveUp(); + break; + case Qt::Key_Down: + dynamic_cast(item)->moveDown(); + break; + } + } + } + } + + if ((event->modifiers()& Qt::ShiftModifier) && m_changeSizeMode && (!(event->modifiers()& Qt::ControlModifier))) { + foreach(QGraphicsItem * item, selectedItems()) { + if (dynamic_cast(item)) { + switch (event->key()) { + case Qt::Key_Right: + dynamic_cast(item)->sizeRight(); + break; + case Qt::Key_Left: + dynamic_cast(item)->sizeLeft(); + break; + case Qt::Key_Up: + dynamic_cast(item)->sizeUp(); + break; + case Qt::Key_Down: + dynamic_cast(item)->sizeDown(); + break; + } + } + } + } +} + +void PageDesignIntf::keyReleaseEvent(QKeyEvent *event) +{ + if ((event->key() == Qt::Key_Control) && m_changePosMode) { + checkSizeOrPosChanges(); + } + + if ((event->key() == Qt::Key_Shift) && m_changeSizeMode ) { + checkSizeOrPosChanges(); + } + + QGraphicsScene::keyReleaseEvent(event); +} + +void PageDesignIntf::startInsertMode(const QString &ItemType) +{ + if (m_insertMode) emit itemInsertCanceled(m_insertItemType); + + emit insertModeStarted(); + m_insertMode = true; + m_insertItemType = ItemType; + m_itemInsertRect = this->addRect(0, 0, 200, 50); + m_itemInsertRect->setVisible(false); + m_itemInsertRect->setParentItem(pageItem()); +} + +void PageDesignIntf::startEditMode() +{ + if (m_insertMode) emit itemInsertCanceled(m_insertItemType); + + finalizeInsertMode(); + m_insertMode = false; +} + +PageItemDesignIntf *PageDesignIntf::pageItem() +{ + return m_pageItem.data(); +} + +void PageDesignIntf::setPageItem(PageItemDesignIntf::Ptr pageItem) +{ + if (!m_pageItem.isNull()) { + removeItem(m_pageItem.data()); + m_pageItem->setParent(0); + } + m_pageItem = pageItem; + m_pageItem->setItemMode(itemMode()); + setSceneRect(pageItem->rect().adjusted(-10*mmFACTOR,-10*mmFACTOR,10*mmFACTOR,10*mmFACTOR)); + addItem(m_pageItem.data()); + registerItem(m_pageItem.data()); +} + +void PageDesignIntf::setPageItems(QList pages) +{ + if (!m_pageItem.isNull()) { + removeItem(m_pageItem.data()); + m_pageItem.clear(); + } + int curHeight = 0; + int curWidth = 0; + m_reportPages = pages; + foreach (PageItemDesignIntf::Ptr pageItem, pages) { + pageItem->setItemMode(itemMode()); + addItem(pageItem.data()); + registerItem(pageItem.data()); + pageItem->setPos(0,curHeight); + curHeight+=pageItem->height()+20; + if (curWidthwidth()) curWidth=pageItem->width(); + } + setSceneRect(QRectF(0,0,curWidth,curHeight).adjusted(-10*mmFACTOR,-10*mmFACTOR,10*mmFACTOR,10*mmFACTOR)); + +} + +void PageDesignIntf::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (m_insertMode) { + finalizeInsertMode(); + CommandIf::Ptr command = InsertItemCommand::create(this, m_insertItemType, event->scenePos(), QSize(200, 50)); + saveCommand(command); + emit itemInserted(this, event->scenePos(), m_insertItemType); + } + if (event->buttons() & Qt::LeftButton && event->modifiers()==Qt::ShiftModifier){ + m_startSelectionPoint = event->scenePos(); + } else { + QGraphicsScene::mousePressEvent(event); + } +} + +void PageDesignIntf::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + + if (event->buttons() & Qt::LeftButton) { + if (!m_changePosOrSizeMode) { + saveSelectedItemsPos(); + saveSelectedItemsGeometry(); + m_changePosOrSizeMode = true; + } + } + + if (event->buttons() & Qt::LeftButton && event->modifiers()==Qt::ShiftModifier){ + if (!m_selectionRect){ + m_selectionRect = new QGraphicsRectItem(); + QBrush brush(QColor(140,190,30,50)); + m_selectionRect->setBrush(brush); + m_selectionRect->setPen(Qt::DashLine); + addItem(m_selectionRect); + } + m_selectionRect->setRect(m_startSelectionPoint.x(),m_startSelectionPoint.y(), + event->scenePos().x()-m_startSelectionPoint.x(), + event->scenePos().y()-m_startSelectionPoint.y()); + setSelectionRect(m_selectionRect->rect()); + } + + if ((m_insertMode) && (pageItem()->rect().contains(pageItem()->mapFromScene(event->scenePos())))) { + if (!m_itemInsertRect->isVisible()) m_itemInsertRect->setVisible(true); + m_itemInsertRect->setPos(pageItem()->mapFromScene(event->scenePos())); + } + else { if (m_insertMode) m_itemInsertRect->setVisible(false); } + + QGraphicsScene::mouseMoveEvent(event); +} + +void PageDesignIntf::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + if ( (event->button() == Qt::LeftButton)) { + checkSizeOrPosChanges(); + } + if (m_selectionRect) { + delete m_selectionRect; + m_selectionRect = 0; + } + QGraphicsScene::mouseReleaseEvent(event); +} + +void PageDesignIntf::setSelectionRect(QRectF selectionRect){ + clearSelection(); + foreach(QGraphicsItem* item, items()){ + if ( selectionRect.intersects(item->mapRectToScene(item->boundingRect()))) + if (dynamic_cast(item)) + item->setSelected(true); + } +} + +BaseDesignIntf *PageDesignIntf::addBand(const QString &bandType) +{ + return internalAddBand(bandType); +} + +BaseDesignIntf *PageDesignIntf::addBand(BandDesignIntf::BandsType bandType) +{ + return internalAddBand(bandType); +} + +template +BaseDesignIntf *PageDesignIntf::internalAddBand(T bandType) +{ + + QSet needParentBands; + needParentBands << BandDesignIntf::SubDetailBand + << BandDesignIntf::SubDetailHeader + << BandDesignIntf::SubDetailFooter + << BandDesignIntf::GroupHeader + << BandDesignIntf::GroupFooter; + + BandsManager bandsManager; + BandDesignIntf *band = bandsManager.createBand(bandType, pageItem(), pageItem()); + + if (band->isUnique()) { + if (pageItem()->isBandExists(bandType)) { + delete band; + return 0; + } + } + + band->setObjectName(genObjectName(*band)); + band->setItemTypeName("Band"); + + BandDesignIntf* pb = 0; + if (selectedItems().count() > 0) { + pb = dynamic_cast(selectedItems().at(0)); + } + + bool increaseBandIndex = false; + int bandIndex = pageItem()->calcBandIndex(band->bandType(), pb, increaseBandIndex); + band->setBandIndex(bandIndex); + if (needParentBands.contains(band->bandType())){ + band->setParentBand(pb); + } + if (increaseBandIndex) pageItem()->increaseBandIndex(bandIndex); + + registerItem(band); + foreach(QGraphicsItem * item, selectedItems()) item->setSelected(false); + band->setSelected(true); + CommandIf::Ptr command = InsertBandCommand::create(this, band->objectName()); + saveCommand(command, false); + return band; +} + +void PageDesignIntf::bandGeometryChanged(QObject* /*object*/, QRectF newGeometry, QRectF oldGeometry) +{ + Q_UNUSED(newGeometry); + Q_UNUSED(oldGeometry); + pageItem()->relocateBands(); +} + +BaseDesignIntf *PageDesignIntf::addReportItem(const QString &itemType, QPointF pos, QSizeF size) +{ + BandDesignIntf *band=0; + foreach(QGraphicsItem * item, items(pos)) { + band = dynamic_cast(item); + if (band) break; + } + + if (band) { + BaseDesignIntf *reportItem = addReportItem(itemType, band, band); + reportItem->setPos(band->mapFromScene(pos)); + reportItem->setSize(size); + return reportItem; + } else { + BaseDesignIntf *reportItem = addReportItem(itemType, pageItem(), pageItem()); + reportItem->setPos(pageItem()->mapFromScene(pos)); + reportItem->setSize(size); + ItemDesignIntf* ii = dynamic_cast(reportItem); + if (ii) + ii->setItemLocation(ItemDesignIntf::Page); + return reportItem; + } + + return 0; +} + +BaseDesignIntf *PageDesignIntf::addReportItem(const QString &itemType, QObject *owner, LimeReport::BaseDesignIntf *parent) +{ + BaseDesignIntf *item = LimeReport::DesignElementsFactory::instance().objectCreator(itemType)((owner) ? owner : pageItem(), (parent) ? parent : pageItem()); + item->setObjectName(genObjectName(*item)); + item->setItemTypeName(itemType); + registerItem(item); + return item; +} + +BaseDesignIntf *PageDesignIntf::createReportItem(const QString &itemType, QObject* owner, BaseDesignIntf* parent) +{ + return LimeReport::DesignElementsFactory::instance().objectCreator(itemType)((owner) ? owner : pageItem(), (parent) ? parent : pageItem()); +} + +CommandIf::Ptr createBandDeleteCommand(PageDesignIntf* page, BandDesignIntf* band){ + + if (band->hasChildren()){ + CommandIf::Ptr command = CommandGroup::create(); + command->addCommand(DeleteItemCommand::create(page,band),false); + foreach(BandDesignIntf* curband, band->childBands()){ + command->addCommand(createBandDeleteCommand(page,curband),false); + } + return command; + } else { + CommandIf::Ptr command = DeleteItemCommand::create(page,band); + return command; + } +} + +void PageDesignIntf::removeReportItem(BaseDesignIntf *item, bool createComand) +{ + + if (!createComand){ + removeItem(item); + BandDesignIntf* band = dynamic_cast(item); + if (band){ + emit bandRemoved(this,band); + } else { + emit itemRemoved(this,item); + } + delete item; + } else { + + BandDesignIntf* band = dynamic_cast(item); + if (band){ + CommandIf::Ptr command = createBandDeleteCommand(this,band); + saveCommand(command); + } else { + LayoutDesignIntf* layout = dynamic_cast(item->parent()); + if (layout && (layout->childrenCount()==2)){ + CommandGroup::Ptr commandGroup = CommandGroup::create(); + commandGroup->addCommand(DeleteLayoutCommand::create(this, layout),false); + commandGroup->addCommand(DeleteItemCommand::create(this,item),false); + saveCommand(commandGroup); + } else { + CommandIf::Ptr command = (dynamic_cast(item))? + DeleteLayoutCommand::create(this, dynamic_cast(item)) : + DeleteItemCommand::create(this, item) ; + saveCommand(command); + } + } + } + +} + +bool PageDesignIntf::saveCommand(CommandIf::Ptr command, bool runCommand) +{ + if (m_executingCommand||m_isLoading) return false; + if (runCommand) { + m_executingCommand = true; + if (!command->doIt()) { + m_executingCommand = false; + return false; + } + m_executingCommand = false; + } + + if (m_currentCommand < (m_commandsList.count() - 1)) + m_commandsList.remove(m_currentCommand + 1, m_commandsList.size() - (m_currentCommand + 1)); + + m_commandsList.push_back(command); + m_currentCommand = m_commandsList.count() - 1; + m_hasHanges = true; + emit commandHistoryChanged(); + return true; +} + +bool PageDesignIntf::isCanRedo() +{ + return m_currentCommand < m_commandsList.count() - 1; +} + +bool PageDesignIntf::isCanUndo() +{ + return m_currentCommand >= 0; +} + +bool PageDesignIntf::isHasChanges() +{ + return (m_commandsList.count() > 0) && m_hasHanges; +} + +bool PageDesignIntf::isItemInsertMode() +{ + return m_insertMode; +} + +void PageDesignIntf::bandPosChanged(QObject * /*object*/, QPointF /*newPos*/, QPointF /*oldPos*/) +{ + //relocateBands(dynamic_cast(object)); +} + +QString PageDesignIntf::genObjectName(const QObject &object) +{ + int index = 1; + QString className(object.metaObject()->className()); + className = className.right(className.length() - (className.lastIndexOf("::") + 2)); + + QString tmpName = QString("%1%2").arg(className).arg(index); + + while (isExistsObjectName(tmpName)) { + index++; + tmpName = QString("%1%2").arg(className).arg(index); + } + + return tmpName; +} + +bool PageDesignIntf::isExistsObjectName(const QString &objectName) const +{ + QObject *item = 0; + + for (int i = 0; i < items().count(); i++) { + item = dynamic_cast(items()[i]); + + if (item) + if (item->objectName() == objectName) return true; + } + + return false; +} + +QRectF PageDesignIntf::getRectByPageSize(PageDesignIntf::PageSize pageSize) +{ + if (m_pageSize != Custom) { + QPrinter printer; + printer.setOutputFormat(QPrinter::PdfFormat); + printer.setOrientation((QPrinter::Orientation)getOrientation()); + printer.setPageSize((QPrinter::PageSize)pageSize); + return QRectF(0, 0, printer.paperRect(QPrinter::Millimeter).width() * 10, + printer.paperSize(QPrinter::Millimeter).height() * 10); + } + + else { + return QRectF(0, 0, m_pageSizeValue.width() * 10, + m_pageSizeValue.height() * 10); + } +} + +bool PageDesignIntf::isLoading() +{ + return m_isLoading; +} + +void PageDesignIntf::objectLoadStarted() +{ + m_isLoading=true; +} + +void PageDesignIntf::objectLoadFinished() +{ + m_isLoading=false; +} + +void PageDesignIntf::removeBand(BandDesignIntf *band) +{ + removeItem(band); + pageItem()->removeBand(band); +} + +ReportEnginePrivate *PageDesignIntf::reportEditor() +{ + return m_reportEditor; +} + +void PageDesignIntf::dragEnterEvent(QGraphicsSceneDragDropEvent *event) +{ + + if (!event->mimeData()->text().isEmpty()){ + event->setDropAction(Qt::CopyAction); + event->accept(); + } else { + event->setDropAction(Qt::IgnoreAction); + event->ignore(); + } +} + +void PageDesignIntf::dragMoveEvent(QGraphicsSceneDragDropEvent* /**event*/) +{ +// event->setDropAction(Qt::CopyAction); +// event->accept(); +} + +void PageDesignIntf::dropEvent(QGraphicsSceneDragDropEvent* event) +{ + +// if (m_itemInsertRect) { +// removeItem(m_itemInsertRect); +// delete m_itemInsertRect; +// m_itemInsertRect = 0; +// } + +// if (event->mimeData()->text() == "Text Item") { +// addReportItem(event->mimeData()->text(), event->scenePos(), QSizeF(200, 50)); +// } + +// else addBand(event->mimeData()->text()); + BaseDesignIntf* item = addReportItem("TextItem",event->scenePos(),QSize(250, 50)); + TextItem* ti = dynamic_cast(item); + ti->setContent(event->mimeData()->text()); + +} + +void PageDesignIntf::dragLeaveEvent(QGraphicsSceneDragDropEvent *) +{ + //removeItem(m_itemInsertRect); + //delete m_itemInsertRect; + //m_itemInsertRect = 0; +} + +QStringList PageDesignIntf::posibleParentItems() +{ + QStringList itemsList; + foreach(QGraphicsItem * item, items()) { + BandDesignIntf *band = dynamic_cast(item); + + if (band) { + itemsList.append(band->objectName()); + } + } + return itemsList; +} + +void PageDesignIntf::slotPageGeomertyChanged(QObject *, QRectF /*newGeometry*/, QRectF) +{ + if (!m_isLoading){ + pageItem()->relocateBands(); + updatePageRect(); + emit geometryChanged(sceneRect()); + } +} + +void PageDesignIntf::slotItemPropertyChanged(QString propertyName, const QVariant &oldValue, const QVariant& newValue) +{ + if (!m_isLoading && m_animationList.isEmpty()){ + saveChangeProppertyCommand(sender()->objectName(),propertyName,oldValue,newValue); + emit itemPropertyChanged(sender()->objectName(),propertyName,oldValue,newValue); + } +} + +void PageDesignIntf::slotItemPropertyObjectNameChanged(const QString &oldName, const QString &newName) +{ + if (oldName.compare(newName)!=0 && !m_executingCommand){ + CommandIf::Ptr command = PropertyObjectNameChangedCommand::create(this, oldName, newName); + saveCommand(command, false); + } +} + +void PageDesignIntf::bandDeleted(QObject *band) +{ + pageItem()->removeBand(reinterpret_cast(band)); + delete band; + pageItem()->relocateBands(); +} + +void PageDesignIntf::slotPageItemLoaded(QObject *) +{ + setItemMode(m_itemMode); +} + +void PageDesignIntf::slotSelectionChanged() +{ + if (selectedItems().count() == 1) { + m_firstSelectedItem = dynamic_cast(selectedItems().at(0)); + } +} + +void PageDesignIntf::slotAnimationStoped(QObject *animation) +{ + m_animationList.removeOne(animation); +} + +void PageDesignIntf::finalizeInsertMode() +{ + if (m_insertMode) { + m_insertMode = false; + if (m_itemInsertRect) { + removeItem(m_itemInsertRect); + delete m_itemInsertRect; + m_itemInsertRect = 0; + } + } +} + +void PageDesignIntf::saveSelectedItemsPos() +{ + m_positionStamp.clear(); + foreach(QGraphicsItem * item, selectedItems()) { + BaseDesignIntf *reportItem = dynamic_cast(item); + + if (reportItem) { + ReportItemPos rp; + rp.objectName = reportItem->objectName(); + rp.pos = reportItem->pos(); + m_positionStamp.push_back(rp); + } + } +} + +void PageDesignIntf::saveSelectedItemsGeometry() +{ + m_geometryStamp.clear(); + foreach(QGraphicsItem * item, selectedItems()) { + BaseDesignIntf *reportItem = dynamic_cast(item); + + if (reportItem) { + ReportItemSize rs; + rs.objectName = reportItem->objectName(); + rs.size = reportItem->size(); + m_geometryStamp.append(rs); + } + } +} + +void PageDesignIntf::checkSizeOrPosChanges() +{ + + if ((selectedItems().count() > 0) && (m_positionStamp.count() > 0)) { + if (m_positionStamp[0].pos != selectedItems().at(0)->pos()) { + createChangePosCommand(); + } + + m_positionStamp.clear(); + } + + if ((selectedItems().count() > 0) && (m_geometryStamp.count() > 0)) { + BaseDesignIntf *reportItem = dynamic_cast(selectedItems()[0]); + + if (reportItem && (m_geometryStamp[0].size != reportItem->size())) { + createChangeSizeCommand(); + } + + m_geometryStamp.clear(); + } + + m_changeSizeMode = false; + m_changePosMode = false; + m_changePosOrSizeMode = false; + +} + +void PageDesignIntf::createChangePosCommand() +{ + QVector newPoses; + foreach(ReportItemPos itemPos, m_positionStamp) { + BaseDesignIntf *reportItem = reportItemByName(itemPos.objectName); + + if (reportItem) { + ReportItemPos newPos; + newPos.objectName = reportItem->objectName(); + newPos.pos = reportItem->pos(); + newPoses.append(newPos); + } + } + CommandIf::Ptr command = PosChangedCommand::create(this, m_positionStamp, newPoses); + saveCommand(command); +} + +void PageDesignIntf::createChangeSizeCommand() +{ + QVector newSizes; + + foreach(ReportItemSize itemPos, m_geometryStamp) { + BaseDesignIntf *reportItem = reportItemByName(itemPos.objectName); + + if (reportItem) { + ReportItemSize newSize; + newSize.objectName = reportItem->objectName(); + newSize.size = reportItem->size(); + newSizes.append(newSize); + } + } + CommandIf::Ptr command = SizeChangedCommand::create(this, m_geometryStamp, newSizes); + saveCommand(command); +} + +void PageDesignIntf::reactivatePageItem(PageItemDesignIntf::Ptr pageItem) +{ + pageItem->setItemMode(itemMode()); + if (pageItem.data()->scene()!=this) + addItem(pageItem.data()); +} + +void PageDesignIntf::animateItem(BaseDesignIntf *item) +{ + if (item && (item->metaObject()->indexOfProperty("backgroundColor")>-1)){ + + foreach (QObject* obj, m_animationList) { + QPropertyAnimation* animation = dynamic_cast(obj); + if (animation->targetObject() == item) return; + } + + QPropertyAnimation* ani1 = new QPropertyAnimation(item,"backgroundColor"); + m_animationList.append(ani1); + + QColor startColor = QColor(Qt::red); + QColor endColor = item->backgroundColor(); + + ani1->setDuration(500); + ani1->setEasingCurve(QEasingCurve::Linear); + ani1->setStartValue(startColor); + ani1->setEndValue(endColor); + ani1->start(QAbstractAnimation::DeleteWhenStopped); + + + connect(ani1,SIGNAL(destroyed(QObject*)), this, SLOT(slotAnimationStoped(QObject*))); + } +} + +void PageDesignIntf::registerItem(BaseDesignIntf *item) +{ + item->setItemMode(itemMode()); + BandDesignIntf *band = dynamic_cast(item); + if (band){ + registerBand(band); + connect(band, SIGNAL(propertyObjectNameChanged(QString,QString)), this, SLOT(slotItemPropertyObjectNameChanged(QString,QString))); + emit bandAdded(this,band); + } else { + connect(item, SIGNAL(propertyChanged(QString,QVariant,QVariant)), this, SLOT(slotItemPropertyChanged(QString,QVariant,QVariant))); + connect(item, SIGNAL(propertyObjectNameChanged(QString,QString)), this, SLOT(slotItemPropertyObjectNameChanged(QString,QString))); + emit itemAdded(this,item); + } +} + +void PageDesignIntf::emitRegisterdItem(BaseDesignIntf *item){ + emit itemAdded(this,item); +} + +void PageDesignIntf::emitItemRemoved(BaseDesignIntf *item) +{ + BandDesignIntf* band = dynamic_cast(item); + if (band){ + emit bandRemoved(this,band); + } else { + emit itemRemoved(this,item); + } +} +void PageDesignIntf::registerBand(BandDesignIntf *band) +{ + if (pageItem()&&!pageItem()->isBandRegistred(band)) { + pageItem()->registerBand(band); + if (itemMode() == DesignMode) pageItem()->relocateBands(); + } +} + +void PageDesignIntf::slotUpdateItemSize() +{ + foreach(QGraphicsItem * item, items()) { + BandDesignIntf *reportBand = dynamic_cast(item); + + if (reportBand) reportBand->updateItemSize(); + } +} + +void PageDesignIntf::saveChangeProppertyCommand(const QString &objectName, const QString &propertyName, const QVariant &oldPropertyValue, const QVariant &newPropertyValue) +{ + if (!m_executingCommand) { + CommandIf::Ptr command = PropertyChangedCommand::create(this, objectName, propertyName, oldPropertyValue, newPropertyValue); + saveCommand(command, false); + } +} + +void PageDesignIntf::changeSelectedGroupProperty(const QString &name, const QVariant &value) +{ + if ((selectedItems().count() > 0) && m_firstSelectedItem) { + CommandGroup::Ptr cm = CommandGroup::create(); + m_executingCommand = true; + foreach(QGraphicsItem * item, selectedItems()) { + BaseDesignIntf *bdItem = dynamic_cast(item); + if (bdItem) { + QVariant oldValue = bdItem->property(name.toLatin1()); + if (oldValue.isValid()){ + bdItem->setProperty(name.toLatin1(),value); + CommandIf::Ptr command = PropertyChangedCommand::create(this, bdItem->objectName(), name, oldValue, value); + cm->addCommand(command, false); + } + } + } + m_executingCommand = false; + saveCommand(cm, false); + } +} + +void PageDesignIntf::undo() +{ + if (m_currentCommand >= 0) { + m_executingCommand = true; + m_commandsList.at(m_currentCommand)->undoIt(); + m_currentCommand--; + m_hasHanges = true; + m_executingCommand = false; + } +} + +void PageDesignIntf::redo() +{ + if (m_currentCommand < m_commandsList.count() - 1) { + m_executingCommand = true; + m_currentCommand++; + m_commandsList.at(m_currentCommand)->doIt(); + m_hasHanges = true; + m_executingCommand = false; + } +} + +void PageDesignIntf::copy() +{ + if (!selectedItems().isEmpty()) { + QClipboard *clipboard = QApplication::clipboard(); + ItemsWriterIntf *writer = new XMLWriter; + bool shouldWrite = false; + foreach(QGraphicsItem * item, selectedItems()) { + ItemDesignIntf *reportItem = dynamic_cast(item); + + if (reportItem) { + writer->putItem(reportItem); + shouldWrite = true; + } + } + + if (shouldWrite) { + clipboard->setText(writer->saveToString()); + } + } +} + +void PageDesignIntf::paste() +{ + QClipboard *clipboard = QApplication::clipboard(); + + if (selectedItems().count() == 1) { + BandDesignIntf *band = dynamic_cast(selectedItems().at(0)); + if (band) { + CommandIf::Ptr command = PasteCommand::create(this, clipboard->text(), band); + saveCommand(command); + } else { + PageItemDesignIntf* page = dynamic_cast(selectedItems().at(0)); + if (page){ + CommandIf::Ptr command = PasteCommand::create(this, clipboard->text(), page); + saveCommand(command); + } + } + } +} + +void PageDesignIntf::deleteSelected() +{ + foreach(QGraphicsItem* item, selectedItems()){ + removeReportItem(dynamic_cast(item),false); + } +} + +void PageDesignIntf::cut() +{ + CommandIf::Ptr command = CutCommand::create(this); + saveCommand(command); +} + +void PageDesignIntf::setToSaved() +{ + m_hasHanges = false; +} + +void PageDesignIntf::bringToFront() +{ + foreach(QGraphicsItem * item, selectedItems()) { + qreal zOrder = 0; + foreach(QGraphicsItem * colItem, collidingItems(item)) { + if (zOrder <= colItem->zValue()) + zOrder = colItem->zValue() + 0.1; + } + BaseDesignIntf *bdItem = dynamic_cast(item); + + if (bdItem) + saveChangeProppertyCommand(bdItem->objectName(), "zOrder", bdItem->zValue(), zOrder); + + item->setZValue(zOrder); + } +} + +void PageDesignIntf::sendToBack() +{ + foreach(QGraphicsItem * item, selectedItems()) { + qreal zOrder = 0; + foreach(QGraphicsItem * colItem, collidingItems(item)) { + if (zOrder >= colItem->zValue()) + zOrder = colItem->zValue() - 0.1; + } + BaseDesignIntf *bdItem = dynamic_cast(item); + + if (bdItem) + saveChangeProppertyCommand(bdItem->objectName(), "zOrder", bdItem->zValue(), zOrder); + + item->setZValue(zOrder); + } +} + +void PageDesignIntf::alignToLeft() +{ + if ((selectedItems().count() > 0) && m_firstSelectedItem) { + CommandGroup::Ptr cm = CommandGroup::create(); + foreach(QGraphicsItem * item, selectedItems()) { + BaseDesignIntf *bdItem = dynamic_cast(item); + if (bdItem) { + QRectF oldGeometry = bdItem->geometry(); + bdItem->setPos(QPoint(m_firstSelectedItem->pos().x(), item->pos().y())); + CommandIf::Ptr command = PropertyChangedCommand::create(this, bdItem->objectName(), "geometry", oldGeometry, bdItem->geometry()); + cm->addCommand(command, false); + } + } + saveCommand(cm, false); + } +} + +void PageDesignIntf::alignToRigth() +{ + if ((selectedItems().count() > 0) && m_firstSelectedItem) { + CommandGroup::Ptr cm = CommandGroup::create(); + foreach(QGraphicsItem * item, selectedItems()) { + BaseDesignIntf *bdItem = dynamic_cast(item); + if (bdItem) { + QRectF oldGeometry = bdItem->geometry(); + bdItem->setPos(QPoint(m_firstSelectedItem->geometry().right() - bdItem->width(), bdItem->pos().y())); + CommandIf::Ptr command = PropertyChangedCommand::create(this, bdItem->objectName(), "geometry", oldGeometry, bdItem->geometry()); + cm->addCommand(command, false); + } + } + saveCommand(cm, false); + } +} + +void PageDesignIntf::alignToVCenter() +{ + if ((selectedItems().count() > 0) && m_firstSelectedItem) { + CommandGroup::Ptr cm = CommandGroup::create(); + foreach(QGraphicsItem * item, selectedItems()) { + BaseDesignIntf *bdItem = dynamic_cast(item); + if (bdItem) { + QRectF oldGeometry = bdItem->geometry(); + bdItem->setPos(QPoint((m_firstSelectedItem->geometry().right() - m_firstSelectedItem->width() / 2) - bdItem->width() / 2, bdItem->pos().y())); + CommandIf::Ptr command = PropertyChangedCommand::create(this, bdItem->objectName(), "geometry", oldGeometry, bdItem->geometry()); + cm->addCommand(command, false); + } + } + saveCommand(cm, false); + } +} + +void PageDesignIntf::alignToTop() +{ + if ((selectedItems().count() > 0) && m_firstSelectedItem) { + CommandGroup::Ptr cm = CommandGroup::create(); + foreach(QGraphicsItem * item, selectedItems()) { + BaseDesignIntf *bdItem = dynamic_cast(item); + if (bdItem) { + QRectF oldGeometry = bdItem->geometry(); + bdItem->setPos(QPoint(bdItem->pos().x(), m_firstSelectedItem->pos().y())); + CommandIf::Ptr command = PropertyChangedCommand::create(this, bdItem->objectName(), "geometry", oldGeometry, bdItem->geometry()); + cm->addCommand(command, false); + } + } + saveCommand(cm, false); + } +} + +void PageDesignIntf::alignToBottom() +{ + if ((selectedItems().count() > 0) && m_firstSelectedItem) { + CommandGroup::Ptr cm = CommandGroup::create(); + foreach(QGraphicsItem * item, selectedItems()) { + BaseDesignIntf *bdItem = dynamic_cast(item); + if (bdItem) { + QRectF oldGeometry = bdItem->geometry(); + bdItem->setPos(QPoint(bdItem->pos().x(), m_firstSelectedItem->geometry().bottom() - bdItem->height())); + CommandIf::Ptr command = PropertyChangedCommand::create(this, bdItem->objectName(), "geometry", oldGeometry, bdItem->geometry()); + cm->addCommand(command, false); + } + } + saveCommand(cm, false); + } +} + +void PageDesignIntf::alignToHCenter() +{ + if ((selectedItems().count() > 0) && m_firstSelectedItem) { + CommandGroup::Ptr cm = CommandGroup::create(); + foreach(QGraphicsItem * item, selectedItems()) { + BaseDesignIntf *bdItem = dynamic_cast(item); + if (bdItem) { + QRectF oldGeometry = bdItem->geometry(); + bdItem->setPos(QPoint(bdItem->pos().x(), (m_firstSelectedItem->geometry().bottom() - m_firstSelectedItem->height() / 2) - bdItem->height() / 2)); + CommandIf::Ptr command = PropertyChangedCommand::create(this, bdItem->objectName(), "geometry", oldGeometry, bdItem->geometry()); + cm->addCommand(command, false); + } + } + saveCommand(cm, false); + } +} + +void PageDesignIntf::sameWidth() +{ + if ((selectedItems().count() > 0) && m_firstSelectedItem) { + CommandGroup::Ptr cm = CommandGroup::create(); + foreach(QGraphicsItem * item, selectedItems()) { + BaseDesignIntf *bdItem = dynamic_cast(item); + if (bdItem) { + QRectF oldGeometry = bdItem->geometry(); + bdItem->setWidth(m_firstSelectedItem->width()); + CommandIf::Ptr command = PropertyChangedCommand::create(this, bdItem->objectName(), "geometry", oldGeometry, bdItem->geometry()); + cm->addCommand(command, false); + } + } + saveCommand(cm, false); + } +} + +void PageDesignIntf::sameHeight() +{ + if ((selectedItems().count() > 0) && m_firstSelectedItem) { + CommandGroup::Ptr cm = CommandGroup::create(); + foreach(QGraphicsItem * item, selectedItems()) { + BaseDesignIntf *bdItem = dynamic_cast(item); + if (bdItem) { + QRectF oldGeometry = bdItem->geometry(); + bdItem->setHeight(m_firstSelectedItem->height()); + CommandIf::Ptr command = PropertyChangedCommand::create(this, bdItem->objectName(), "geometry", oldGeometry, bdItem->geometry()); + cm->addCommand(command, false); + } + } + saveCommand(cm, false); + } +} + +void PageDesignIntf::addHLayout() +{ + + if (selectedItems().size()==0) return; + + QList si = selectedItems(); + QList::iterator it = si.begin(); + for (; it != si.end();) { + if (!dynamic_cast(*it)) { + (*it)->setSelected(false); + it = si.erase(it); + } + else ++it; + } + + it = si.begin(); + QGraphicsItem* elementsParent = (*it)->parentItem(); + for (; it != si.end();++it) { + if ((*it)->parentItem()!=elementsParent){ + QMessageBox::information(0,QObject::tr("Attention!"),QObject::tr("Selected elements have different parent containers")); + return; + } + } + + CommandIf::Ptr cm = InsertHLayoutCommand::create(this); + saveCommand(cm,true); +} + +bool hLayoutLessThen(QGraphicsItem *c1, QGraphicsItem *c2) +{ + return c1->pos().x() < c2->pos().x(); +} + +HorizontalLayout* PageDesignIntf::internalAddHLayout() +{ + if (m_firstSelectedItem && (selectedItems().count() > 1)) { + + QList si = selectedItems(); + QList::iterator it = si.begin(); + qSort(si.begin(), si.end(), hLayoutLessThen); + it = si.begin(); + + if (si.count() > 1) { + + it = si.begin(); + BaseDesignIntf *firstElement = dynamic_cast(*it); + + HorizontalLayout *layout = new HorizontalLayout(firstElement->parent(), firstElement->parentItem()); + layout->setPos(firstElement->pos()); + layout->setWidth(0); + layout->setHeight(firstElement->height()); + + for (; it != si.end(); ++it) { + BaseDesignIntf *bdItem = dynamic_cast(*it); + layout->addChild(bdItem); + } + + foreach(QGraphicsItem * item, selectedItems()) { + item->setSelected(false); + } + + layout->setSelected(true); + layout->setObjectName(genObjectName(*layout)); + layout->setItemTypeName("HorizontalLayout"); + registerItem(layout); + return layout; + } + } + return 0; +} + +void PageDesignIntf::setFont(const QFont& font) +{ + changeSelectedGroupProperty("font",font); +} + +void PageDesignIntf::setTextAlign(const Qt::Alignment& alignment) +{ + changeSelectedGroupProperty("alignment",QVariant(alignment)); +} + +void PageDesignIntf::setBorders(const BaseDesignIntf::BorderLines& border) +{ + changeSelectedGroupProperty("borders", (int)border); +} + +void PageDesignIntf::removeAllItems() +{ + pageItem()->clear(); + m_commandsList.clear(); +} + +void PageDesignIntf::setItemMode(BaseDesignIntf::ItemMode state) +{ + m_itemMode = state; + foreach(QGraphicsItem * item, items()) { + BaseDesignIntf *reportItem = dynamic_cast(item); + + if (reportItem) { + reportItem->setItemMode(itemMode()); + } + } +} + +BaseDesignIntf* PageDesignIntf::reportItemByName(const QString &name) +{ + + foreach(QGraphicsItem * item, items()) { + BaseDesignIntf *bd = dynamic_cast(item); + if (bd && (bd->objectName().compare(name, Qt::CaseInsensitive) == 0)) return bd; + } + + return 0; +} + +QList PageDesignIntf::reportItemsByName(const QString &name){ + QList result; + foreach(QGraphicsItem * item, items()) { + BaseDesignIntf *bd = dynamic_cast(item); + if (bd && (bd->objectName().compare(name, Qt::CaseInsensitive) == 0)) result.append(bd); + } + return result; +} + +void CommandIf::addCommand(Ptr command, bool execute) +{ + Q_UNUSED(command) + Q_UNUSED(execute) +} + +CommandIf::Ptr InsertItemCommand::create(PageDesignIntf *page, const QString &itemType, QPointF pos, QSizeF size) +{ + InsertItemCommand *command = new InsertItemCommand(); + command->setPage(page); + command->setType(itemType); + command->setPos(pos); + command->setSize(size); + return CommandIf::Ptr(command); +} + +bool InsertItemCommand::doIt() +{ + BaseDesignIntf *item = page()->addReportItem(m_itemType, m_pos, m_size); + if (item) m_itemName = item->objectName(); + return item != 0; +} + +void InsertItemCommand::undoIt() +{ + BaseDesignIntf *item = page()->reportItemByName(m_itemName); + if (item){ + page()->removeReportItem(item,false); + } +// page()->removeItem(item); +// delete item; +} + +CommandIf::Ptr DeleteItemCommand::create(PageDesignIntf *page, BaseDesignIntf *item) +{ + DeleteItemCommand *command = new DeleteItemCommand(); + //QScopedPointer writer(new XMLWriter()); + //writer->putItem(item); + command->setPage(page); + command->setItem(item); + LayoutDesignIntf* layout = dynamic_cast(item->parent()); + if (layout) + command->m_layoutName = layout->objectName(); + //command->m_itemXML = writer->saveToString(); + return CommandIf::Ptr(command); +} + +bool DeleteItemCommand::doIt() +{ + BaseDesignIntf *item = page()->reportItemByName(m_itemName); + if (item) { + item->beforeDelete(); + page()->removeItem(item); + page()->emitItemRemoved(item); + delete item; + return true; + } + return false; +} + +void DeleteItemCommand::undoIt() +{ + BaseDesignIntf *item = page()->createReportItem(m_itemType); + ItemsReaderIntf::Ptr reader = StringXMLreader::create(m_itemXML); + if (reader->first()) reader->readItem(item); + BandDesignIntf* band = dynamic_cast(item); + if (band){ + bool increaseBandIndex = false; + BandDesignIntf* parentBand = dynamic_cast(page()->reportItemByName(band->parentBandName())); + band->setBandIndex(page()->pageItem()->calcBandIndex(band->bandType(), parentBand, increaseBandIndex)); + if (increaseBandIndex) + page()->pageItem()->increaseBandIndex(band->bandIndex()); + } + page()->registerItem(item); + + if (!m_layoutName.isEmpty()) { + LayoutDesignIntf* layout = dynamic_cast(page()->reportItemByName(m_layoutName)); + if (layout){ + layout->restoreChild(item); + } + page()->emitRegisterdItem(item); + } +} + +void DeleteItemCommand::setItem(BaseDesignIntf *value) +{ + m_itemName = value->objectName(); + m_itemType = value->storageTypeName(); + QScopedPointer writer(new XMLWriter()); + writer->putItem(value); + m_itemXML = writer->saveToString(); +} + +CommandIf::Ptr DeleteLayoutCommand::create(PageDesignIntf *page, LayoutDesignIntf *item) +{ + DeleteLayoutCommand* command = new DeleteLayoutCommand(); + command->setPage(page); + command->setItem(item); + foreach (BaseDesignIntf* item, item->childBaseItems()){ + command->m_childItems.append(item->objectName()); + } + return CommandIf::Ptr(command); +} + +bool DeleteLayoutCommand::doIt() +{ + BaseDesignIntf *item = page()->reportItemByName(m_itemName); + if (item) { + item->beforeDelete(); + QScopedPointer writer(new XMLWriter()); + writer->putItem(item); + m_itemXML = writer->saveToString(); + page()->removeItem(item); + page()->emitItemRemoved(item); + delete item; + return true; + } + return false; +} + +void DeleteLayoutCommand::undoIt() +{ + BaseDesignIntf *item = page()->addReportItem(m_itemType); + ItemsReaderIntf::Ptr reader = StringXMLreader::create(m_itemXML); + if (reader->first()) reader->readItem(item); + foreach(QString ci, m_childItems){ + BaseDesignIntf* ri = page()->reportItemByName(ci); + if (ri){ + dynamic_cast(item)->addChild(ri); + } + page()->emitRegisterdItem(item); + } +} + +void DeleteLayoutCommand::setItem(BaseDesignIntf *item) +{ + m_itemName = item->objectName(); + m_itemType = item->storageTypeName(); +} + +CommandIf::Ptr PasteCommand::create(PageDesignIntf *page, const QString &itemsXML, BaseDesignIntf *parent) +{ + PasteCommand *command = new PasteCommand(); + command->setPage(page); + command->setItemsXML(itemsXML); + command->setParent(parent); + return CommandIf::Ptr(command); +} + +bool PasteCommand::doIt() +{ + m_itemNames.clear(); + ItemsReaderIntf::Ptr reader = StringXMLreader::create(m_itemsXML); + + if (reader->first() && reader->itemType() == "Object") { + insertItem(reader); + + while (reader->next()) { + insertItem(reader); + } + } + + else return false; + + page()->selectedItems().clear(); + foreach(QString name, m_itemNames) { + page()->reportItemByName(name)->setSelected(true); + } + return m_itemNames.count() > 0; +} + +void PasteCommand::undoIt() +{ + foreach(QString name, m_itemNames) { + BaseDesignIntf *item = page()->reportItemByName(name); + page()->emitItemRemoved(item); + page()->removeItem(item); + delete item; + } +} + +void PasteCommand::setItemsXML(const QString &itemsXML) +{ + m_itemsXML = itemsXML; +} + +bool PasteCommand::insertItem(ItemsReaderIntf::Ptr reader) +{ + BaseDesignIntf* parentItem = page()->reportItemByName(m_parentItemName); + if (parentItem){ + BaseDesignIntf *item = page()->addReportItem(reader->itemClassName(), parentItem, parentItem); + if (item) { + m_itemNames.push_back(item->objectName()); + reader->readItem(item); + item->setParent(parentItem); + item->setParentItem(parentItem); + item->setObjectName(m_itemNames.last()); + } + return true; + } + return false; +} + +CommandIf::Ptr CutCommand::create(PageDesignIntf *page) +{ + CutCommand *command = new CutCommand(); + command->setPage(page); + ItemsWriterIntf *writer = new XMLWriter(); + foreach(QGraphicsItem * item, page->selectedItems()) { + BaseDesignIntf *reportItem = dynamic_cast(item); + + if (reportItem) { + command->m_itemNames.push_back(reportItem->objectName()); + writer->putItem(reportItem); + } + } + command->setXML(writer->saveToString()); + + if (command->m_itemNames.count() > 0) { + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setText(writer->saveToString()); + } + + return CommandIf::Ptr(command); +} + +bool CutCommand::doIt() +{ + foreach(QString name, m_itemNames) { + BaseDesignIntf *item = page()->reportItemByName(name); + page()->removeItem(item); + page()->emitItemRemoved(item); + delete item; + } + return m_itemNames.count() > 0; +} + +void CutCommand::undoIt() +{ + ItemsReaderIntf::Ptr reader = StringXMLreader::create(m_itemsXML); + + if (reader->first()) { + BaseDesignIntf *item = page()->addReportItem(reader->itemClassName()); + + if (item) reader->readItem(item); + + while (reader->next()) { + item = page()->addReportItem(reader->itemClassName()); + + if (item) reader->readItem(item); + } + } +} + +CommandIf::Ptr PosChangedCommand::create(PageDesignIntf *page, QVector &oldPos, QVector &newPos) +{ + PosChangedCommand *command = new PosChangedCommand(); + command->setPage(page); + command->m_newPos = newPos; + command->m_oldPos = oldPos; + return CommandIf::Ptr(command); +} + +bool PosChangedCommand::doIt() +{ + for (int i = 0; i < m_newPos.count(); i++) { + BaseDesignIntf *reportItem = page()->reportItemByName(m_newPos[i].objectName); + + if (reportItem && (reportItem->pos() != m_newPos[i].pos)) reportItem->setPos(m_newPos[i].pos); + } + + return true; +} + +void PosChangedCommand::undoIt() +{ + for (int i = 0; i < m_oldPos.count(); i++) { + BaseDesignIntf *reportItem = page()->reportItemByName(m_oldPos[i].objectName); + + if (reportItem && (reportItem->pos() != m_oldPos[i].pos)) reportItem->setPos(m_oldPos[i].pos); + } +} + +CommandIf::Ptr SizeChangedCommand::create(PageDesignIntf *page, QVector &oldSize, QVector &newSize) +{ + SizeChangedCommand *command = new SizeChangedCommand(); + command->setPage(page); + command->m_newSize = newSize; + command->m_oldSize = oldSize; + return CommandIf::Ptr(command); +} + +bool SizeChangedCommand::doIt() +{ + for (int i = 0; i < m_newSize.count(); i++) { + BaseDesignIntf *reportItem = page()->reportItemByName(m_newSize[i].objectName); + + if (reportItem && (reportItem->size() != m_newSize[i].size)) reportItem->setSize(m_newSize[i].size); + } + + return true; +} + +void SizeChangedCommand::undoIt() +{ + for (int i = 0; i < m_oldSize.count(); i++) { + BaseDesignIntf *reportItem = page()->reportItemByName(m_oldSize[i].objectName); + + if (reportItem && (reportItem->size() != m_oldSize[i].size)) reportItem->setSize(m_oldSize[i].size); + } +} + +CommandIf::Ptr PropertyChangedCommand::create(PageDesignIntf *page, const QString &objectName, const QString &propertyName, + const QVariant &oldValue, const QVariant &newValue) +{ + PropertyChangedCommand *command = new PropertyChangedCommand(); + command->setPage(page); + command->m_objectName = objectName; + command->m_propertyName = propertyName; + command->m_oldValue = oldValue; + command->m_newValue = newValue; + return CommandIf::Ptr(command); +} + +bool PropertyChangedCommand::doIt() +{ + BaseDesignIntf *reportItem = page()->reportItemByName(m_objectName); + + if (reportItem && (reportItem->property(m_propertyName.toLatin1()) != m_newValue)) { + reportItem->setProperty(m_propertyName.toLatin1(), m_newValue); + } + + return true; +} + +void PropertyChangedCommand::undoIt() +{ + BaseDesignIntf *reportItem = page()->reportItemByName(m_objectName); + + if (reportItem && (reportItem->property(m_propertyName.toLatin1()) != m_oldValue)) { + reportItem->setProperty(m_propertyName.toLatin1(), m_oldValue); + } +} + +CommandIf::Ptr InsertBandCommand::create(PageDesignIntf *page, const QString &bandName) +{ + InsertBandCommand *command = new InsertBandCommand(); + command->setPage(page); + BandDesignIntf *band = dynamic_cast(page->reportItemByName(bandName)); + command->m_bandType = band->bandType(); + command->m_bandName = band->objectName(); + if (band->parentBand()) + command->m_parentBandName = band->parentBandName(); + return CommandIf::Ptr(command); +} + +bool InsertBandCommand::doIt() +{ + if (!m_parentBandName.isEmpty() && page()->reportItemByName(m_parentBandName)) + page()->reportItemByName(m_parentBandName)->setSelected(true); + BaseDesignIntf *item = page()->addBand(m_bandType); + + if (item) { + m_bandName = item->objectName(); + return true; + } + + return false; +} + +void InsertBandCommand::undoIt() +{ + BaseDesignIntf *item = page()->reportItemByName(m_bandName); + + if (item) { + page()->removeReportItem(item,false); + } +} + +CommandIf::Ptr CommandGroup::create() +{ + return CommandIf::Ptr(new CommandGroup); +} + +bool CommandGroup::doIt() +{ + foreach(CommandIf::Ptr command, m_commands) { + if (!command->doIt()) + return false; + } + return true; +} + +void CommandGroup::undoIt() +{ + foreach(CommandIf::Ptr command, m_commands) { + command->undoIt(); + } +} + +void CommandGroup::addCommand(CommandIf::Ptr command, bool execute) +{ + if (execute && command->doIt()) + m_commands.append(command); + + else + m_commands.append(command); +} + +PrintRange::PrintRange(QAbstractPrintDialog::PrintRange rangeType, int fromPage, int toPage) + :m_rangeType(rangeType), m_fromPage(fromPage), m_toPage(toPage) +{} + +CommandIf::Ptr InsertHLayoutCommand::create(PageDesignIntf *page) +{ + InsertHLayoutCommand *command = new InsertHLayoutCommand(); + command->setPage(page); + + QList si = page->selectedItems(); + QList::iterator it = si.begin(); + + BaseDesignIntf* parentItem = dynamic_cast((*it)->parentItem()); + command->m_oldParentName = (parentItem)?(parentItem->objectName()):""; + + for(it = si.begin();it!=si.end();++it){ + BaseDesignIntf* bi = dynamic_cast(*it); + if (bi) + command->m_elements.insert(bi->objectName(),bi->pos()); + } + + return CommandIf::Ptr(command); +} + +bool InsertHLayoutCommand::doIt() +{ + foreach (QString itemName, m_elements.keys()) { + BaseDesignIntf* bi = page()->reportItemByName(itemName); + if (bi) + bi->setSelected(true); + } + LayoutDesignIntf* layout = page()->internalAddHLayout(); + if (layout) + m_layoutName = layout->objectName(); + return layout != 0; +} + +void InsertHLayoutCommand::undoIt() +{ + HorizontalLayout* layout = dynamic_cast(page()->reportItemByName(m_layoutName)); + if (layout){ + foreach(QGraphicsItem* item, layout->childBaseItems()){ + BaseDesignIntf* bi = dynamic_cast(item); + BaseDesignIntf* parent = page()->reportItemByName(m_oldParentName); + if (bi && parent){ + bi->setParentItem(parent); + bi->setParent(parent); + bi->setPos(m_elements.value(bi->objectName())); + } + } + page()->removeReportItem(layout,false); + } +} + +CommandIf::Ptr PropertyObjectNameChangedCommand::create(PageDesignIntf *page, const QString &oldValue, const QString &newValue) +{ + PropertyObjectNameChangedCommand *command = new PropertyObjectNameChangedCommand(); + command->setPage(page); + command->m_oldName = oldValue; + command->m_newName = newValue; + return CommandIf::Ptr(command); +} + +bool PropertyObjectNameChangedCommand::doIt() +{ + BaseDesignIntf *reportItem = page()->reportItemByName(m_oldName); + + if (reportItem ) { + reportItem->setObjectName(m_newName); + reportItem->emitObjectNamePropertyChanged(m_oldName,m_newName); + return true; + } + return false; +} + +void PropertyObjectNameChangedCommand::undoIt() +{ + BaseDesignIntf *reportItem = page()->reportItemByName(m_newName); + + if (reportItem ) { + reportItem->setObjectName(m_oldName); + reportItem->emitObjectNamePropertyChanged(m_newName,m_oldName); + } + +} + +} + diff --git a/src/lrpagedesignintf.h b/src/lrpagedesignintf.h new file mode 100644 index 0000000..17f1509 --- /dev/null +++ b/src/lrpagedesignintf.h @@ -0,0 +1,409 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRPAGEDEDIGNITF_H +#define LRPAGEDEDIGNITF_H + +#include +#include + +#include "lrpageitemdesignintf.h" +#include "serializators/lrstorageintf.h" +#include "lrbanddesignintf.h" + +namespace LimeReport { + + class BaseDesignIntf; + class ReportEnginePrivate; + class PropertyChangedCommand; + class HorizontalLayout; + class LayoutDesignIntf; + + class CommandIf { + public: + virtual ~CommandIf(){} + typedef QSharedPointer Ptr; + virtual bool doIt() = 0; + virtual void undoIt() = 0; + virtual void addCommand(CommandIf::Ptr command,bool execute); + }; + + typedef QList::const_iterator BandsIterator; + + struct ReportItemPos{ + QString objectName; + QPointF pos; + }; + + struct ReportItemSize{ + QString objectName; + QSizeF size; + }; + + class PageDesignIntf : public QGraphicsScene, public ObjectLoadingStateIntf{ + Q_OBJECT + Q_PROPERTY(QObject* pageItem READ pageItem()) + public: + friend class PropertyChangedCommand; + friend class InsertHLayoutCommand; + enum Orientation {Portrait, Landscape}; + enum PageSize {A4, B5, Letter, Legal, Executive, + A0, A1, A2, A3, A5, A6, A7, A8, A9, B0, B1, + B10, B2, B3, B4, B6, B7, B8, B9, C5E, Comm10E, + DLE, Folio, Ledger, Tabloid, Custom, NPageSize = Custom + }; + + explicit PageDesignIntf(QObject* parent = 0); + ~PageDesignIntf(); + void updatePageRect(); + Orientation getOrientation(); + + void setPageSize(PageSize sizeType, QSizeF sizeValue=QSizeF()); + PageSize pageSize() const; + + void startInsertMode(const QString& ItemType); + void startEditMode(); + + PageItemDesignIntf *pageItem(); + void setPageItem(PageItemDesignIntf::Ptr pageItem); + void setPageItems(QList pages); + + bool isItemInsertMode(); + ReportEnginePrivate* reportEditor(); + void setReportEditor(ReportEnginePrivate* value){m_reportEditor=value;} + + QStringList posibleParentItems(); + void registerItem(BaseDesignIntf* item); + void registerBand(BandDesignIntf* band); + void removeAllItems(); + + void setItemMode(BaseDesignIntf::ItemMode state); + BaseDesignIntf::ItemMode itemMode(){return m_itemMode;} + BaseDesignIntf* reportItemByName(const QString& name); + QList reportItemsByName(const QString &name); + BaseDesignIntf* addReportItem(const QString& itemType, QPointF pos, QSizeF size); + BaseDesignIntf* addReportItem(const QString& itemType, QObject *owner=0, BaseDesignIntf *parent=0); + BaseDesignIntf* createReportItem(const QString& itemType, QObject *owner=0, BaseDesignIntf *parent=0); + void removeReportItem(BaseDesignIntf* item, bool createComand = true); + bool saveCommand(CommandIf::Ptr command, bool runCommand = true); + + bool isCanRedo(); + bool isCanUndo(); + bool isHasChanges(); + + void reactivatePageItem(PageItemDesignIntf::Ptr pageItem); + + void setSettings(QSettings* settings){ m_settings = settings;} + QSettings* settings(){ return m_settings;} + + QString genObjectName(const QObject& object); + + void animateItem(BaseDesignIntf* item); + void setSelectionRect(QRectF selectionRect); + void emitRegisterdItem(BaseDesignIntf *item); + void emitItemRemoved(BaseDesignIntf* item); + + + protected: + + virtual void keyPressEvent(QKeyEvent *event); + virtual void keyReleaseEvent(QKeyEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + + virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *event); + virtual void dragMoveEvent(QGraphicsSceneDragDropEvent *); + virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent *event); + virtual void dropEvent(QGraphicsSceneDragDropEvent *event); + + LimeReport::BandDesignIntf::BandsType findPriorType(LimeReport::BandDesignIntf::BandsType bandType); + + + bool isExistsObjectName (const QString& objectName) const; + QRectF getRectByPageSize(PageSize pageSize); + + bool isLoading(); + void objectLoadStarted(); + void objectLoadFinished(); + + HorizontalLayout* internalAddHLayout(); + signals: + void geometryChanged(QRectF newGeometry); + void insertModeStarted(); + void itemInserted(LimeReport::PageDesignIntf* report, QPointF pos, const QString& ItemType); + void itemInsertCanceled(const QString& ItemType); + void itemSelected(LimeReport::BaseDesignIntf *item); + void multiItemsSelected(QList* objectsList); + void commandHistoryChanged(); + void itemPropertyChanged(const QString& objectName, const QString& propertyName, const QVariant& oldValue, const QVariant& newValue); + void itemAdded(LimeReport::PageDesignIntf* report, LimeReport::BaseDesignIntf* item); + void itemRemoved(LimeReport::PageDesignIntf* report, LimeReport::BaseDesignIntf* item); + void bandAdded(LimeReport::PageDesignIntf* report, LimeReport::BandDesignIntf* band); + void bandRemoved(LimeReport::PageDesignIntf* report, LimeReport::BandDesignIntf* band); + public slots: + BaseDesignIntf* addBand(const QString& bandType); + BaseDesignIntf* addBand(BandDesignIntf::BandsType bandType); + void removeBand(LimeReport::BandDesignIntf* band); + void bandGeometryChanged(QObject* object, QRectF newGeometry, QRectF oldGeometry); + void bandPosChanged(QObject* object, QPointF newPos, QPointF oldPos); + void slotUpdateItemSize(); + void undo(); + void redo(); + void copy(); + void paste(); + void deleteSelected(); + void cut(); + void setToSaved(); + void bringToFront(); + void sendToBack(); + void alignToLeft(); + void alignToRigth(); + void alignToVCenter(); + void alignToTop(); + void alignToBottom(); + void alignToHCenter(); + void sameWidth(); + void sameHeight(); + void addHLayout(); + void setFont(const QFont &font); + void setTextAlign(const Qt::Alignment& alignment); + void setBorders(const BaseDesignIntf::BorderLines& border); + private slots: + void slotPageGeomertyChanged(QObject*, QRectF, QRectF ); + void slotItemPropertyChanged(QString propertyName, const QVariant &oldValue, const QVariant &newValue); + void slotItemPropertyObjectNameChanged(const QString& oldName, const QString& newName); + void bandDeleted(QObject* band); + void slotPageItemLoaded(QObject *); + void slotSelectionChanged(); + void slotAnimationStoped(QObject *animation); + private: + template + BaseDesignIntf* internalAddBand(T bandType); + void finalizeInsertMode(); + void saveSelectedItemsPos(); + void saveSelectedItemsGeometry(); + void checkSizeOrPosChanges(); + void createChangePosCommand(); + void createChangeSizeCommand(); + void saveChangeProppertyCommand(const QString& objectName, const QString& propertyName, const QVariant& oldPropertyValue, const QVariant& newPropertyValue); + void changeSelectedGroupProperty(const QString& name,const QVariant& value); + private: + PageSize m_pageSize; + QSizeF m_pageSizeValue; + Orientation m_orientation; + QRectF m_geometry; + LimeReport::PageItemDesignIntf::Ptr m_pageItem; + QList m_reportPages; + ReportEnginePrivate* m_reportEditor; + bool m_insertMode; + QGraphicsItem * m_itemInsertRect; + QString m_insertItemType; + BaseDesignIntf::ItemMode m_itemMode; + QGraphicsRectItem* m_cutterBorder; + QGraphicsRectItem* m_pageRect; + QVector m_commandsList; + QVector m_positionStamp; + QVector m_geometryStamp; + BaseDesignIntf* m_firstSelectedItem; + int m_currentCommand; + bool m_changeSizeMode; + bool m_changePosMode; + bool m_changePosOrSizeMode; + bool m_executingCommand; + bool m_hasHanges; + bool m_isLoading; + bool m_executingGroupCommand; + QSettings* m_settings; + QList m_animationList; + QPointF m_startSelectionPoint; + QGraphicsRectItem* m_selectionRect; + }; + + class AbstractPageCommand : public CommandIf{ + public: + void setPage(PageDesignIntf* value){m_page = value;} + PageDesignIntf* page(){return m_page;} + private: + PageDesignIntf* m_page; + }; + + class InsertHLayoutCommand : public AbstractPageCommand{ + public: + static CommandIf::Ptr create(PageDesignIntf* page); + bool doIt(); + void undoIt(); + private: + InsertHLayoutCommand(){} + private: + QString m_layoutName; + QString m_oldParentName; + QMap m_elements; + }; + + class InsertItemCommand : public AbstractPageCommand{ + public: + static CommandIf::Ptr create(PageDesignIntf* page, const QString& itemType, QPointF pos, QSizeF size); + bool doIt(); + void undoIt(); + void setPos(QPointF& value){m_pos = value;} + QPointF pos(){return m_pos;} + void setSize(QSizeF& value){m_size=value;} + QSizeF size(){return m_size;} + void setType(const QString& value){m_itemType=value;} + private: + InsertItemCommand(){} + private: + QPointF m_pos; + QSizeF m_size; + QString m_itemType; + QString m_itemName; + }; + + class InsertBandCommand : public AbstractPageCommand{ + public: + static CommandIf::Ptr create(PageDesignIntf* page,const QString& bandName); + bool doIt(); + void undoIt(); + private: + BandDesignIntf::BandsType m_bandType; + QString m_bandName; + QString m_parentBandName; + }; + + class DeleteItemCommand : public AbstractPageCommand{ + public: + static CommandIf::Ptr create(PageDesignIntf* page, BaseDesignIntf* item); + bool doIt(); + void undoIt(); + void setType(const QString& value){m_itemType=value;} + void setXml(const QString& value){m_itemXML=value;} + void setItem(BaseDesignIntf* value); + private: + QString m_itemXML; + QString m_itemType; + QString m_itemName; + QString m_layoutName; + }; + + class DeleteLayoutCommand : public AbstractPageCommand{ + public: + static CommandIf::Ptr create(PageDesignIntf* page, LayoutDesignIntf* item); + bool doIt(); + void undoIt(); + protected: + void setItem(BaseDesignIntf* item); + private: + QStringList m_childItems; + QString m_itemXML; + QString m_itemType; + QString m_itemName; + }; + + + class PasteCommand : public AbstractPageCommand{ + public: + static CommandIf::Ptr create(PageDesignIntf* page, const QString& itemsXML, BaseDesignIntf *parent); + bool doIt(); + void undoIt(); + protected: + void setItemsXML(const QString& itemsXML); + void setParent(BaseDesignIntf* parent){m_parentItemName = parent->objectName();} + bool insertItem(ItemsReaderIntf::Ptr reader); + private: + QString m_itemsXML; + QString m_parentItemName; + QVector m_itemNames; + }; + + class CutCommand : public AbstractPageCommand{ + public: + static CommandIf::Ptr create(PageDesignIntf* page); + bool doIt(); + void undoIt(); + void setXML(const QString& value){m_itemsXML=value;} + private: + QString m_itemsXML; + QVector m_itemNames; + }; + + class PosChangedCommand : public AbstractPageCommand{ + public: + static CommandIf::Ptr create(PageDesignIntf* page, QVector& oldPos, QVector& newPos); + bool doIt(); + void undoIt(); + private: + QVector m_oldPos; + QVector m_newPos; + }; + + class SizeChangedCommand : public AbstractPageCommand{ + public: + static CommandIf::Ptr create(PageDesignIntf* page, QVector& oldSize, QVector& newSize); + bool doIt(); + void undoIt(); + private: + QVector m_oldSize; + QVector m_newSize; + }; + + class PropertyChangedCommand : public AbstractPageCommand{ + public: + static CommandIf::Ptr create(PageDesignIntf* page, const QString& objectName, const QString& propertyName, const QVariant& oldValue, const QVariant& newValue); + bool doIt(); + void undoIt(); + private: + QString m_objectName; + QString m_propertyName; + QVariant m_oldValue; + QVariant m_newValue; + }; + + class PropertyObjectNameChangedCommand : public AbstractPageCommand{ + public: + static CommandIf::Ptr create(PageDesignIntf* page, const QString &oldValue, const QString &newValue); + bool doIt(); + void undoIt(); + private: + QString m_oldName; + QString m_newName; + }; + + class CommandGroup : public AbstractPageCommand{ + public: + static CommandIf::Ptr create(); + bool doIt(); + void undoIt(); + void addCommand(CommandIf::Ptr command,bool execute); + private: + QList m_commands; + }; + +} +#endif //LRPAGEDEDIGNITF_H diff --git a/src/lrpageitemdesignintf.cpp b/src/lrpageitemdesignintf.cpp new file mode 100644 index 0000000..7862e6e --- /dev/null +++ b/src/lrpageitemdesignintf.cpp @@ -0,0 +1,486 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrpageitemdesignintf.h" +#include "lrbanddesignintf.h" +#include +#include + +namespace LimeReport { + +bool bandSortBandLessThenByIndex(const BandDesignIntf *c1, const BandDesignIntf *c2){ + if (c1->bandIndex()!=c2->bandIndex()){ + return c1->bandIndex()bandIndex(); + } else { + return c1->bandType()bandType(); + } +} + +PageItemDesignIntf::PageItemDesignIntf(QObject *owner, QGraphicsItem *parent) : + BaseDesignIntf("PageItem",owner,parent), + m_topMargin(0), m_bottomMargin(0), m_leftMargin(0), m_rightMargin(0), + m_pageOrientaion(Portrait), m_pageSize(A4), m_sizeChainging(false) +{ + setFixedPos(true); + setPosibleResizeDirectionFlags(Fixed); + initPageSize(m_pageSize); +} + +PageItemDesignIntf::PageItemDesignIntf(const PageSize pageSize, const QRectF &rect, QObject *owner, QGraphicsItem *parent) : + BaseDesignIntf("PageItem",owner,parent), + m_topMargin(0), m_bottomMargin(0), m_leftMargin(0), m_rightMargin(0), + m_pageOrientaion(Portrait), m_pageSize(pageSize), m_sizeChainging(false) +{ + setFixedPos(true); + setPosibleResizeDirectionFlags(Fixed); + initPageSize(rect.size()); +} + +PageItemDesignIntf::~PageItemDesignIntf() +{ + foreach(BandDesignIntf* band,m_bands) band->disconnect(this); + m_bands.clear(); +} + +void PageItemDesignIntf::paint(QPainter *ppainter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + + if (itemMode() & DesignMode){ + ppainter->save(); + ppainter->setOpacity(0.8); + ppainter->fillRect(boundingRect(),pageBorderColor()); + ppainter->setOpacity(1); + ppainter->fillRect(pageRect(),Qt::white); + paintGrid(ppainter); + ppainter->setPen(gridColor()); + ppainter->drawRect(boundingRect()); + ppainter->restore(); + } + + if (itemMode() & PreviewMode) { + ppainter->save(); + ppainter->fillRect(rect(),Qt::white); + QPen pen; + pen.setColor(Qt::gray); + pen.setWidth(2); + pen.setStyle(Qt::DotLine); + ppainter->setPen(pen); + QRectF tmpRect = rect(); + tmpRect.adjust(-4,-4,4,4); + ppainter->drawRect(tmpRect); + ppainter->restore(); + BaseDesignIntf::paint(ppainter,option,widget); + } +} + +BaseDesignIntf *PageItemDesignIntf::createSameTypeItem(QObject *owner, QGraphicsItem *parent) +{ + return new PageItemDesignIntf(owner,parent); +} + +void PageItemDesignIntf::geometryChangedEvent(QRectF newRect, QRectF) +{ +// if (scene()) +// scene()->setSceneRect(newRect); + Q_UNUSED(newRect) + updateMarginRect(); + PageSize oldSize = m_pageSize; + if (!m_sizeChainging && !isLoading()) + m_pageSize = Custom; + notify("pageSize",oldSize,m_pageSize); +} + +QColor PageItemDesignIntf::selectionColor() const +{ + return Qt::gray; +} + +QColor PageItemDesignIntf::pageBorderColor() const +{ + //return QColor(180,220,150); + return QColor(100,150,50); +} + +QColor PageItemDesignIntf::gridColor() const +{ + //return QColor(240,240,240); + return QColor(170,200,150); +} + +void PageItemDesignIntf::clear() +{ + foreach(QGraphicsItem* item, childItems()){ + delete item; + } + childItems().clear(); + m_bands.clear(); +} + +BandDesignIntf *PageItemDesignIntf::bandByType(BandDesignIntf::BandsType bandType) const +{ + QList::const_iterator it = childBands().constBegin(); + for(;it!=childBands().constEnd();++it){ + if ( (*it)->bandType()==bandType) return (*it); + } return 0; +} + +bool PageItemDesignIntf::isBandExists(BandDesignIntf::BandsType bandType) +{ + foreach(BandDesignIntf* band,childBands()){ + if (band->bandType()==bandType) return true; + } + return false; +} + +bool PageItemDesignIntf::isBandExists(const QString &bandType) +{ + foreach(BandDesignIntf* band, m_bands){ + if (band->bandTitle()==bandType) return true; + } + return false; +} + +BandDesignIntf* PageItemDesignIntf::bandByIndex(int index) +{ + foreach(BandDesignIntf* band,m_bands){ + if (band->bandIndex()==index) return band; + } + return 0; +} + +BandDesignIntf *PageItemDesignIntf::bandByName(QString bandObjectName) +{ + foreach(BandDesignIntf* band, childBands()){ + if (band->objectName().compare(bandObjectName,Qt::CaseInsensitive)==0){ + return band; + } + } + return 0; +} + +int PageItemDesignIntf::calcBandIndex(BandDesignIntf::BandsType bandType, BandDesignIntf *parentBand, bool& increaseBandIndex) +{ + + increaseBandIndex = false; + QSet subDetailsBands; + subDetailsBands << BandDesignIntf::SubDetailBand << BandDesignIntf::SubDetailHeader << BandDesignIntf::SubDetailFooter; + + int bandIndex=-1; + qSort(m_bands.begin(),m_bands.end(),bandSortBandLessThenByIndex); + foreach(BandDesignIntf* band,m_bands){ + if ((band->bandType()==BandDesignIntf::GroupHeader)&&(band->bandType()>bandType)) break; + if ((band->bandType()>bandType)&&(band->parentBand()==0)) break; + if (bandIndexbandIndex()) bandIndex=band->bandIndex()+1; + } + + if (bandIndex==-1) { + bandIndex = (int)(bandType); + increaseBandIndex = true; + } + + if (parentBand) { + switch (bandType) { + case BandDesignIntf::SubDetailBand: + bandIndex = parentBand->bandIndex() + 1; + increaseBandIndex = true; + break; + case BandDesignIntf::SubDetailHeader: + bandIndex = parentBand->bandIndex(); + increaseBandIndex = true; + break; + case BandDesignIntf::SubDetailFooter: + bandIndex = parentBand->maxChildIndex(subDetailsBands) + 1; + increaseBandIndex = true; + break; + case BandDesignIntf::GroupHeader: + bandIndex = parentBand->groupHeaderIndex(); + increaseBandIndex = true; + break; + case BandDesignIntf::GroupFooter: + bandIndex = parentBand->parentBand()->groupFooterIndex(parentBand->bandIndex()) + 1; + increaseBandIndex = true; + break; + default : + ; + } + + } + return bandIndex; +} + +void PageItemDesignIntf::increaseBandIndex(int startIndex) +{ + if (bandByIndex(startIndex)){ + foreach(BandDesignIntf* band,m_bands){ + if (band->bandIndex()>=startIndex){ + band->setBandIndex(band->bandIndex()+1); + } + } + } +} + +bool PageItemDesignIntf::isBandRegistred(BandDesignIntf *band) +{ + foreach(BandDesignIntf* cBand,childBands()){ + if (band==cBand) return true; + } + return false; +} + +void PageItemDesignIntf::registerBand(BandDesignIntf *band) +{ + if (!isBandRegistred(band)){ + if (band->bandIndex()>childBands().count()-1) + m_bands.append(band); + else + m_bands.insert(band->bandIndex(),band); + + band->setParent(this); + band->setParentItem(this); + band->setWidth(pageRect().width()); + connect(band, SIGNAL(destroyed(QObject*)),this,SLOT(bandDeleted(QObject*))); + connect(band, SIGNAL(geometryChanged(QObject*,QRectF,QRectF)),this,SLOT(bandGeometryChanged(QObject*,QRectF,QRectF))); + } +} + +void PageItemDesignIntf::relocateBands() +{ + if (isLoading()) return; + + int bandSpace = (itemMode() & DesignMode)?4:0; + + qSort(m_bands.begin(),m_bands.end(),bandSortBandLessThenByIndex); + + if (m_bands.count()>0) m_bands[0]->setPos(pageRect().x(),pageRect().y()); + if(m_bands.count()>1){ + m_bands[0]->setBandIndex(0); + for(int i=0;i<(m_bands.count()-1);i++){ + if ((m_bands[i+1]->bandType()!=BandDesignIntf::PageFooter) || (itemMode() & DesignMode)) + m_bands[i+1]->setPos(pageRect().x(),m_bands[i]->pos().y()+m_bands[i]->height()+bandSpace); + m_bands[i+1]->setBandIndex(i+1); + } + } +} + +void PageItemDesignIntf::removeBand(BandDesignIntf *band) +{ + if (!m_bands.isEmpty()){ + m_bands.removeOne(band); + } +} + +int PageItemDesignIntf::dataBandCount() +{ + int count=0; + foreach(BandDesignIntf* band,m_bands){ + if (band->bandType()==BandDesignIntf::Data) count++; + } + return count; +} + +BandDesignIntf *PageItemDesignIntf::dataBandAt(int index) +{ + int count=0; + qSort(m_bands.begin(),m_bands.end(),bandSortBandLessThenByIndex); + foreach(BandDesignIntf* band,m_bands){ + if (band->bandType()==BandDesignIntf::Data){ + if(count==index) return band; + count++; + } + } + return 0; +} + +void PageItemDesignIntf::setTopMargin(int value) +{ + if (m_topMargin!=value){ + int oldValue = m_topMargin; + m_topMargin=value; + updateMarginRect(); + notify("topMargin",oldValue,value); + } +} + +void PageItemDesignIntf::setBottomMargin(int value) +{ + if (m_bottomMargin!=value){ + int oldValue = m_bottomMargin; + m_bottomMargin=value; + updateMarginRect(); + notify("bottomMargin",oldValue,value); + } +} + +void PageItemDesignIntf::setLeftMargin(int value) +{ + if (m_leftMargin!=value){ + int oldValue = m_leftMargin; + m_leftMargin=value; + updateMarginRect(); + notify("leftMargin",oldValue,value); + } +} + +void PageItemDesignIntf::setRightMargin(int value) +{ + if (m_rightMargin!=value){ + int oldValue = m_rightMargin; + m_rightMargin=value; + updateMarginRect(); + notify("rightMargin",oldValue,value); + } +} + +void PageItemDesignIntf::setPageOrientation(PageItemDesignIntf::Orientation value) +{ + if (!m_sizeChainging && m_pageOrientaion!=value){ + m_sizeChainging = true; + m_pageOrientaion = value; + if (!isLoading()){ + qreal tmpWidth = width(); + setWidth(height()); + setHeight(tmpWidth); + } + m_sizeChainging = false; + } +} + +QSizeF PageItemDesignIntf::getRectByPageSize(const PageSize& size) +{ + if (size != Custom) { + QPrinter printer; + printer.setOutputFormat(QPrinter::PdfFormat); + printer.setOrientation((QPrinter::Orientation)pageOrientation()); + printer.setPageSize((QPrinter::PageSize)size); + return QSizeF(printer.paperRect(QPrinter::Millimeter).width() * 10, + printer.paperSize(QPrinter::Millimeter).height() * 10); + } + + else { + return QSizeF(width(),height()); + } +} + +void PageItemDesignIntf::initPageSize(const QSizeF& size) +{ + m_sizeChainging = true; + setWidth(size.width()); + setHeight(size.height()); + m_sizeChainging=false; +} +void PageItemDesignIntf::initPageSize(const PageItemDesignIntf::PageSize &size) +{ + m_sizeChainging = true; + if (m_pageSize != Custom){ + QSizeF pageSize = getRectByPageSize(size); + setWidth(pageSize.width()); + setHeight(pageSize.height()); + } + m_sizeChainging=false; +} + +void PageItemDesignIntf::setPageSize(const PageSize &size) +{ + if(m_pageSize!=size){ + m_pageSize=size; + initPageSize(m_pageSize); + } +} + +void PageItemDesignIntf::bandDeleted(QObject *band) +{ + removeBand(reinterpret_cast(band)); + relocateBands(); +} + +void PageItemDesignIntf::bandGeometryChanged(QObject *, QRectF /*newGeometry*/, QRectF /*oldGeometry*/) +{ + relocateBands(); +} + +void PageItemDesignIntf::collectionLoadFinished(const QString &collectionName) +{ + if (collectionName.compare("children",Qt::CaseInsensitive)==0){ + m_bands.clear(); +#ifdef HAVE_QT5 + foreach(QObject* obj,children()){ +#else + foreach(QObject* obj,QObject::children()){ +#endif + BandDesignIntf* item = dynamic_cast(obj); + if (item) { + registerBand(item); + } + } + } + BaseDesignIntf::collectionLoadFinished(collectionName); +} + +void PageItemDesignIntf::updateMarginRect() +{ + m_pageRect = rect(); + m_pageRect.adjust(m_leftMargin*mmFactor(),m_topMargin*mmFactor(), + -m_rightMargin*mmFactor(),-m_bottomMargin*mmFactor()); + foreach(BandDesignIntf* band,m_bands){ + band->setWidth(pageRect().width()); + relocateBands(); + } + update(); +} + +void PageItemDesignIntf::paintGrid(QPainter *ppainter) +{ + ppainter->save(); + ppainter->setPen(QPen(gridColor())); + ppainter->setOpacity(0.5); + for (int i=0;i<=(pageRect().height()-50)/100;i++){ + ppainter->drawLine(pageRect().x(),(i*100)+pageRect().y()+50,pageRect().right(),i*100+pageRect().y()+50); + }; + for (int i=0;i<=((pageRect().width()-50)/100);i++){ + ppainter->drawLine(i*100+pageRect().x()+50,pageRect().y(),i*100+pageRect().x()+50,pageRect().bottom()); + }; + + ppainter->setPen(QPen(gridColor())); + ppainter->setOpacity(1); + for (int i=0;i<=(pageRect().width()/100);i++){ + ppainter->drawLine(i*100+pageRect().x(),pageRect().y(),i*100+pageRect().x(),pageRect().bottom()); + }; + for (int i=0;i<=pageRect().height()/100;i++){ + ppainter->drawLine(pageRect().x(),i*100+pageRect().y(),pageRect().right(),i*100+pageRect().y()); + }; + ppainter->drawRect(pageRect()); + ppainter->restore(); +} + +PageItemDesignIntf::Ptr PageItemDesignIntf::create(QObject *owner) +{ + return PageItemDesignIntf::Ptr(new PageItemDesignIntf(owner)); +} + +} diff --git a/src/lrpageitemdesignintf.h b/src/lrpageitemdesignintf.h new file mode 100644 index 0000000..079b621 --- /dev/null +++ b/src/lrpageitemdesignintf.h @@ -0,0 +1,127 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRPAGEITEM_H +#define LRPAGEITEM_H +#include "lrbasedesignintf.h" +#include "lrbanddesignintf.h" +#include +#include + +namespace LimeReport{ + +class ReportRender; +class PageItemDesignIntf : public LimeReport::BaseDesignIntf +{ + Q_OBJECT + Q_ENUMS(Orientation) + Q_ENUMS(PageSize) + Q_PROPERTY(int topMargin READ topMargin WRITE setTopMargin) + Q_PROPERTY(int bottomMargin READ bottomMargin WRITE setBottomMargin) + Q_PROPERTY(int rightMargin READ rightMargin WRITE setRightMargin) + Q_PROPERTY(int leftMargin READ leftMargin WRITE setLeftMargin) + Q_PROPERTY(Orientation pageOrientation READ pageOrientation WRITE setPageOrientation) + Q_PROPERTY(PageSize pageSize READ pageSize WRITE setPageSize ) + friend class ReportRender; +public: + enum Orientation { Portrait, Landscape }; + enum PageSize {A4, B5, Letter, Legal, Executive, + A0, A1, A2, A3, A5, A6, A7, A8, A9, B0, B1, + B10, B2, B3, B4, B6, B7, B8, B9, C5E, Comm10E, + DLE, Folio, Ledger, Tabloid, Custom, NPageSize = Custom + }; + typedef QList BandsList; + typedef QList::const_iterator BandsIterator; + typedef QSharedPointer Ptr; + static PageItemDesignIntf::Ptr create(QObject* owner); + explicit PageItemDesignIntf(QObject *owner = 0, QGraphicsItem* parent=0); + explicit PageItemDesignIntf(const PageSize pageSize, const QRectF& rect,QObject *owner = 0, QGraphicsItem* parent=0); + ~PageItemDesignIntf(); + virtual void paint(QPainter *ppainter, const QStyleOptionGraphicsItem *option, QWidget *widget); + virtual BaseDesignIntf* createSameTypeItem(QObject* owner=0, QGraphicsItem* parent=0); + virtual void geometryChangedEvent(QRectF newRect, QRectF); + virtual QColor selectionColor() const; + virtual QColor pageBorderColor() const; + virtual QColor gridColor() const; + void clear(); + const BandsList& childBands() const {return m_bands;} + BandDesignIntf * bandByType(BandDesignIntf::BandsType bandType) const; + bool isBandExists(BandDesignIntf::BandsType bandType); + bool isBandExists(const QString& bandType); + BandDesignIntf* bandByIndex(int index); + BandDesignIntf* bandByName(QString bandObjectName); + int calcBandIndex(BandDesignIntf::BandsType bandType, BandDesignIntf* parentBand, bool &increaseBandIndex); + void increaseBandIndex(int startIndex); + bool isBandRegistred(BandDesignIntf* band); + void registerBand(BandDesignIntf* band); + void relocateBands(); + void removeBand(BandDesignIntf* band); + + int dataBandCount(); + BandDesignIntf* dataBandAt(int index); + + void setTopMargin(int value); + int topMargin() const {return m_topMargin;} + void setBottomMargin(int value); + int bottomMargin() const {return m_bottomMargin;} + void setLeftMargin(int value); + int leftMargin() const {return m_leftMargin;} + void setRightMargin(int value); + int rightMargin() const{return m_rightMargin;} + + void setPageOrientation(Orientation value); + Orientation pageOrientation() const {return m_pageOrientaion;} + PageSize pageSize() const {return m_pageSize;} + void setPageSize(const PageSize &size); + +protected slots: + void bandDeleted(QObject* band); + void bandGeometryChanged(QObject* /*object*/, QRectF newGeometry, QRectF oldGeometry); +protected: + void collectionLoadFinished(const QString& collectionName); + QRectF& pageRect(){return m_pageRect;} + void updateMarginRect(); + QSizeF getRectByPageSize(const PageSize &size); + void initPageSize(const PageSize &size); + void initPageSize(const QSizeF &size); +private: + void paintGrid(QPainter *ppainter); +private: + int m_topMargin; + int m_bottomMargin; + int m_leftMargin; + int m_rightMargin; + Orientation m_pageOrientaion; + PageSize m_pageSize; + QRectF m_pageRect; + bool m_sizeChainging; + QList m_bands; +}; +} +#endif // LRPAGEITEM_H diff --git a/src/lrpreviewreportwindow.cpp b/src/lrpreviewreportwindow.cpp new file mode 100644 index 0000000..5c4ba90 --- /dev/null +++ b/src/lrpreviewreportwindow.cpp @@ -0,0 +1,410 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrpreviewreportwindow.h" +#include "ui_lrpreviewreportwindow.h" +#include "serializators/lrxmlreader.h" +#include "serializators/lrxmlwriter.h" +#include "lrreportengine_p.h" + +#include +#include +#include +#include + +PreviewReportWindow::PreviewReportWindow(ReportEnginePrivate *report,QWidget *parent, QSettings *settings, Qt::WindowFlags flags) : + QMainWindow(parent,flags), + ui(new Ui::PreviewReportWindow), m_currentPage(1), m_changingPage(false), m_settings(settings), m_ownedSettings(false), + m_priorScrolValue(0) +{ + ui->setupUi(this); + setWindowTitle("Lime Report Preview"); + m_previewPage = report->createPreviewPage(); + m_previewPage->setItemMode( LimeReport::PreviewMode ); + m_pagesNavigator = new QSpinBox(this); + m_pagesNavigator->setMaximum(10000000); + m_pagesNavigator->setPrefix("Page: "); + m_pagesNavigator->setMinimumWidth(120); + ui->toolBar->insertWidget(ui->actionNextPage,m_pagesNavigator); + m_simpleScene = new QGraphicsScene(this); + ui->actionShowMessages->setVisible(false); + ui->errorsView->setVisible(false); + connect(m_pagesNavigator,SIGNAL(valueChanged(int)),this,SLOT(slotPageNavigatorChanged(int))); + connect(ui->graphicsView->verticalScrollBar(),SIGNAL(valueChanged(int)), this, SLOT(slotSliderMoved(int))); + connect(ui->actionShowMessages, SIGNAL(triggered()), this, SLOT(slotShowErrors())); + restoreSetting(); +} + +void PreviewReportWindow::writeSetting() +{ + settings()->beginGroup("PreviewWindow"); + settings()->setValue("Geometry",saveGeometry()); + settings()->setValue("State",saveState()); + settings()->endGroup(); +} + +void PreviewReportWindow::restoreSetting() +{ + settings()->beginGroup("PreviewWindow"); + QVariant v = settings()->value("Geometry"); + if (v.isValid()){ + restoreGeometry(v.toByteArray()); + } + v = settings()->value("State"); + if (v.isValid()){ + restoreState(v.toByteArray()); + } + settings()->endGroup(); +} + + +PreviewReportWindow::~PreviewReportWindow() +{ + if (m_ownedSettings) + delete m_settings; + delete ui; +} + +void PreviewReportWindow::initPreview(int pagesCount) +{ + m_pagesNavigator->setSuffix(tr(" of %1").arg(pagesCount)); + m_pagesNavigator->setMinimum(1); + m_pagesNavigator->setMaximum(pagesCount); + ui->graphicsView->setScene(m_previewPage); + ui->graphicsView->centerOn(0, 0); + ui->graphicsView->scale(0.5,0.5); + m_currentPage=1; + m_pagesNavigator->setValue(m_currentPage); +} + +void PreviewReportWindow::setSettings(QSettings* value) +{ + if (m_ownedSettings) + delete m_settings; + m_settings=value; + m_ownedSettings=false; + restoreSetting(); +} + +void PreviewReportWindow::setErrorMessages(const QStringList &value){ + ui->actionShowMessages->setVisible(true); + foreach (QString line, value) { + ui->errorsView->append(line); + } +} + +QSettings*PreviewReportWindow::settings() +{ + if (m_settings){ + return m_settings; + } else { + m_settings = new QSettings("LimeReport",QApplication::applicationName()); + m_ownedSettings = true; + return m_settings; + } +} + +void PreviewReportWindow::setReportReader(ItemsReaderIntf::Ptr reader) +{ + m_reader=reader; + if (!reader.isNull()){ + if (reader->first()) reader->readItem(m_previewPage->pageItem()); + int pagesCount = reader->firstLevelItemsCount(); + m_previewPage->pageItem()->setItemMode(PreviewMode); + initPreview(pagesCount); + } +} + +void PreviewReportWindow::setPages(ReportPages pages) +{ + m_reportPages = pages; + if (!m_reportPages.isEmpty()){ + //m_previewPage->setPageItem(m_reportPages.at(0)); + m_previewPage->setPageItems(m_reportPages); + m_changingPage = true; + initPreview(m_reportPages.count()); + m_currentPage = 1; + if (pages.at(0)) pages.at(0)->setSelected(true); + m_changingPage = false; + } +} + +void PreviewReportWindow::exec() +{ + bool deleteOnClose = testAttribute(Qt::WA_DeleteOnClose); + setAttribute(Qt::WA_DeleteOnClose,false); + setAttribute(Qt::WA_ShowModal,true); + show(); + m_eventLoop.exec(); + if (deleteOnClose) delete this; +} + +void PreviewReportWindow::closeEvent(QCloseEvent *) +{ +#ifdef Q_OS_WIN + writeSetting(); +#endif +#ifdef Q_OS_MAC + writeSetting(); +#endif + m_eventLoop.exit(); +} + +void PreviewReportWindow::resizeEvent(QResizeEvent* e) +{ +#ifdef Q_OS_UNIX + if (e->oldSize()!=e->size()){ + writeSetting(); + } +#else + Q_UNUSED(e) +#endif +} + +void PreviewReportWindow::moveEvent(QMoveEvent* e) +{ +#ifdef Q_OS_UNIX + if (e->oldPos()!=e->pos()){ + writeSetting(); + } +#else + Q_UNUSED(e) +#endif +} + +void PreviewReportWindow::slotPrint() +{ + QPrinter printer(QPrinter::HighResolution); + QPrintDialog dialog(&printer,QApplication::activeWindow()); + if (dialog.exec()==QDialog::Accepted){ + if (!m_reportPages.isEmpty()) + ReportEnginePrivate::printReport( + m_reportPages, + printer, + PrintRange(dialog.printRange(),dialog.fromPage(),dialog.toPage()) + ); + else ReportEnginePrivate::printReport(m_reader,printer); + foreach(PageItemDesignIntf::Ptr pageItem, m_reportPages){ + m_previewPage->reactivatePageItem(pageItem); + } + + } +} + +void PreviewReportWindow::slotPriorPage() +{ + m_changingPage=true; + if ((!m_reportPages.isEmpty())&&(m_currentPage>1)){ + m_currentPage--; + //m_previewPage->setPageItem(m_reportPages.at(m_currentPage-1)); + ui->graphicsView->ensureVisible( + calcPageShift(m_reportPages.at(m_currentPage-1)), 0, 0 + ); + m_pagesNavigator->setValue(m_currentPage); + } else { + if (reader() && reader()->prior()){ + m_previewPage->removeAllItems(); + reader()->readItem(m_previewPage->pageItem()); + m_currentPage--; + m_pagesNavigator->setValue(m_currentPage); + } + } + m_changingPage=false; +} + +void PreviewReportWindow::slotNextPage() +{ + m_changingPage=true; + if ((!m_reportPages.isEmpty())&&(m_reportPages.count()>(m_currentPage))){ + m_currentPage++; + //m_previewPage->setPageItem(m_reportPages.at(m_currentPage-1)); + ui->graphicsView->ensureVisible( + calcPageShift(m_reportPages.at(m_currentPage-1)), 0, 0 + ); + m_pagesNavigator->setValue(m_currentPage); + } else { + if (reader() && reader()->next()){ + m_previewPage->removeAllItems(); + reader()->readItem(m_previewPage->pageItem()); + m_currentPage++; + m_pagesNavigator->setValue(m_currentPage); + } + } + m_changingPage=false; +} + +void PreviewReportWindow::slotZoomIn() +{ + ui->graphicsView->scale(1.2,1.2); +} + +void PreviewReportWindow::slotZoomOut() +{ + ui->graphicsView->scale(1/1.2,1/1.2); +} + +void PreviewReportWindow::slotPageNavigatorChanged(int value) +{ + if (m_changingPage) return; + m_changingPage = true; + if ((!m_reportPages.isEmpty())&&(m_reportPages.count() >= value)){ + m_currentPage = value; + //m_previewPage->setPageItem(m_reportPages.at(m_currentPage-1)); + ui->graphicsView->ensureVisible( + calcPageShift(m_reportPages.at(m_currentPage-1)), 0, 0 + ); + } else { + if (reader()){ + int direction = (m_currentPage>value)?-1:1; + while (m_currentPage != value){ + if (direction == 1) reader()->next(); + else reader()->prior(); + m_currentPage += direction; + } + m_previewPage->removeAllItems(); + reader()->readItem(m_previewPage->pageItem()); + m_pagesNavigator->setValue(m_currentPage); + } + } + m_changingPage=false; +} + +void PreviewReportWindow::slotShowErrors() +{ + ui->errorsView->setVisible(ui->actionShowMessages->isChecked()); +} + +ItemsReaderIntf *PreviewReportWindow::reader() +{ + return m_reader.data(); +} + +bool PreviewReportWindow::pageIsVisible(PageItemDesignIntf::Ptr page) +{ + return page->mapToScene(page->rect()).boundingRect().intersects( + ui->graphicsView->mapToScene(ui->graphicsView->viewport()->geometry()).boundingRect() + ); +} + +QRectF PreviewReportWindow::calcPageShift(PageItemDesignIntf::Ptr page) +{ + qreal pageHeight = page->mapToScene(page->boundingRect()).boundingRect().height(); + qreal viewHeight = ui->graphicsView->mapToScene( + 0,ui->graphicsView->viewport()->height() + ).y()-ui->graphicsView->mapToScene(0,0).y(); + viewHeight = (pageHeightmapRectToScene( + m_reportPages.at(m_currentPage-1)->rect() + ); + return QRectF(0,pageStartPos.y(),0,viewHeight); +} + +void PreviewReportWindow::on_actionSaveToFile_triggered() +{ + QString fileName = QFileDialog::getSaveFileName(this,tr("Report file name")); + if (!fileName.isEmpty()){ + QScopedPointer< ItemsWriterIntf > writer(new XMLWriter()); + foreach (PageItemDesignIntf::Ptr page, m_reportPages){ + writer->putItem(page.data()); + } + writer->saveToFile(fileName); + } +} + +void PreviewReportWindow::slotFirstPage() +{ + m_changingPage=true; + if ((!m_reportPages.isEmpty())&&(m_currentPage>1)){ + m_currentPage=1; + //m_previewPage->setPageItem(m_reportPages.at(m_currentPage-1)); + ui->graphicsView->ensureVisible( + calcPageShift(m_reportPages.at(m_currentPage-1)), 0, 0 + ); + m_pagesNavigator->setValue(m_currentPage); + } else { + if (reader() && reader()->prior()){ + while (reader()->prior()) { + } + m_previewPage->removeAllItems(); + reader()->readItem(m_previewPage->pageItem()); + m_currentPage=1; + m_pagesNavigator->setValue(m_currentPage); + } + } + m_changingPage=false; +} + +void PreviewReportWindow::slotLastPage() +{ + m_changingPage=true; + if ((!m_reportPages.isEmpty())&&(m_reportPages.count()>(m_currentPage))){ + m_currentPage=m_reportPages.count(); + //m_previewPage->setPageItem(m_reportPages.at(m_currentPage-1)); + ui->graphicsView->ensureVisible( + calcPageShift(m_reportPages.at(m_currentPage-1)), 0, 0 + ); + m_pagesNavigator->setValue(m_currentPage); + } else { + + if (reader() && reader()->next()){ + m_currentPage++; + while (reader()->next()) { + m_currentPage++; + } + m_previewPage->removeAllItems(); + reader()->readItem(m_previewPage->pageItem()); + m_pagesNavigator->setValue(m_currentPage); + } + } + m_changingPage=false; +} + +void PreviewReportWindow::slotSliderMoved(int value) +{ + if (ui->graphicsView->verticalScrollBar()->minimum()==value){ + m_currentPage = 1; + } else if (ui->graphicsView->verticalScrollBar()->maximum()==value){ + m_currentPage = m_reportPages.count(); + } + + if (!pageIsVisible(m_reportPages.at(m_currentPage-1))){ + if (value>m_priorScrolValue){ + m_currentPage++; + } else { + m_currentPage--; + } + } + + m_changingPage = true; + m_pagesNavigator->setValue(m_currentPage); + m_changingPage = false; + m_priorScrolValue = value; + +} + diff --git a/src/lrpreviewreportwindow.h b/src/lrpreviewreportwindow.h new file mode 100644 index 0000000..d6f1bef --- /dev/null +++ b/src/lrpreviewreportwindow.h @@ -0,0 +1,97 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRPREVIEWREPORTWINDOW_H +#define LRPREVIEWREPORTWINDOW_H + +#include +#include +#include + +#include "lrpagedesignintf.h" +#include "lrreportrender.h" +#include "serializators/lrstorageintf.h" +#include "serializators/lrxmlreader.h" + +namespace Ui { +class PreviewReportWindow; +} +using namespace LimeReport; +class PreviewReportWindow : public QMainWindow +{ + Q_OBJECT +public: + explicit PreviewReportWindow(ReportEnginePrivate *report, QWidget *parent = 0, QSettings* settings=0, Qt::WindowFlags flags=0); + ~PreviewReportWindow(); + void setReportReader(ItemsReaderIntf::Ptr reader); + void setPages(ReportPages pages); + void exec(); + void initPreview(int pagesCount); + void setSettings(QSettings* value); + void setErrorMessages(const QStringList& value); + QSettings* settings(); +protected: + void writeSetting(); + void restoreSetting(); + void closeEvent(QCloseEvent *); + void resizeEvent(QResizeEvent *e); + void moveEvent(QMoveEvent *e); +public slots: + void slotPrint(); + void slotPriorPage(); + void slotNextPage(); + void slotZoomIn(); + void slotZoomOut(); + void slotPageNavigatorChanged(int value); + void slotShowErrors(); + void on_actionSaveToFile_triggered(); + void slotFirstPage(); + void slotLastPage(); +private slots: + void slotSliderMoved(int value); +private: + ItemsReaderIntf* reader(); + bool pageIsVisible(PageItemDesignIntf::Ptr page); + QRectF calcPageShift(PageItemDesignIntf::Ptr page); +private: + Ui::PreviewReportWindow *ui; + QSpinBox* m_pagesNavigator; + QSharedPointer m_reader; + int m_currentPage; + PageDesignIntf* m_previewPage; + QGraphicsScene* m_simpleScene; + ReportPages m_reportPages; + QEventLoop m_eventLoop; + bool m_changingPage; + QSettings* m_settings; + bool m_ownedSettings; + int m_priorScrolValue; +}; + +#endif // LRPREVIEWREPORTWINDOW_H diff --git a/src/lrpreviewreportwindow.ui b/src/lrpreviewreportwindow.ui new file mode 100644 index 0000000..b4e2870 --- /dev/null +++ b/src/lrpreviewreportwindow.ui @@ -0,0 +1,367 @@ + + + PreviewReportWindow + + + + 0 + 0 + 800 + 600 + + + + Preview + + + + + 1 + + + 1 + + + 1 + + + 1 + + + + + + + + + + + + + 0 + 0 + 800 + 20 + + + + + View + + + + + + + Report + + + + + + + + + + toolBar + + + + 16 + 16 + + + + TopToolBarArea + + + false + + + + + + + + + + + + + + + + + + + :/report/images/print:/report/images/print + + + Print + + + Ctrl+P + + + + + + :/report/images/zoomIn:/report/images/zoomIn + + + Zoom In + + + + + + :/report/images/zoomOut:/report/images/zoomOut + + + Zoom Out + + + + + + :/report/images/prior:/report/images/prior + + + Prior Page + + + Prior Page + + + + + + :/report/images/next:/report/images/next + + + Next Page + + + Next Page + + + + + + :/report/images/closebox:/report/images/closebox + + + Close Preview + + + Close Preview + + + + + true + + + + :/report/images/edit:/report/images/edit + + + Edit Mode + + + + + + :/report/images/save:/report/images/save + + + Save to file + + + Save to file + + + + + true + + + + :/databrowser/images/error_message_2.png:/databrowser/images/error_message_2.png + + + Show errors + + + Show errors + + + + + + :/report/images/first:/report/images/first + + + First Page + + + First page + + + + + + :/report/images/last:/report/images/last + + + Last Page + + + Last Page + + + + + + + + + + actionPrint + triggered() + PreviewReportWindow + slotPrint() + + + -1 + -1 + + + 399 + 299 + + + + + actionPriorPage + triggered() + PreviewReportWindow + slotPriorPage() + + + -1 + -1 + + + 399 + 299 + + + + + actionNextPage + triggered() + PreviewReportWindow + slotNextPage() + + + -1 + -1 + + + 399 + 299 + + + + + actionZoomIn + triggered() + PreviewReportWindow + slotZoomIn() + + + -1 + -1 + + + 399 + 299 + + + + + actionZoomOut + triggered() + PreviewReportWindow + slotZoomOut() + + + -1 + -1 + + + 399 + 299 + + + + + actionClosePreview + triggered() + PreviewReportWindow + close() + + + -1 + -1 + + + 399 + 299 + + + + + actionFirst_Page + triggered() + PreviewReportWindow + slotFirstPage() + + + -1 + -1 + + + 399 + 299 + + + + + actionLast_Page + triggered() + PreviewReportWindow + slotLastPage() + + + -1 + -1 + + + 399 + 299 + + + + + + slotNextPage() + slotPriorPage() + slotZoomIn() + slotZoomOut() + slotPrint() + slotFirstPage() + slotLastPage() + + diff --git a/src/lrreportdesignwidget.cpp b/src/lrreportdesignwidget.cpp new file mode 100644 index 0000000..ec1453c --- /dev/null +++ b/src/lrreportdesignwidget.cpp @@ -0,0 +1,361 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrreportdesignwidget.h" +#include "serializators/lrxmlreader.h" +#include "serializators/lrxmlwriter.h" +#include "lrreportengine_p.h" +#include "lrbasedesignintf.h" + +#include +#include +#include +#include +#include +#include + + +namespace LimeReport { + +// ReportDesignIntf +ReportDesignWidget* ReportDesignWidget::m_instance=0; + +ReportDesignWidget::ReportDesignWidget(ReportEnginePrivate *report, QMainWindow *mainWindow, QWidget *parent) : + QWidget(parent), m_mainWindow(mainWindow) +{ + QVBoxLayout *mainLayout = new QVBoxLayout(this); + mainLayout->setContentsMargins(1,1,1,1); + m_view = new QGraphicsView(qobject_cast(this)); + m_view->setBackgroundBrush(QBrush(Qt::gray)); + mainLayout->addWidget(m_view); + setLayout(mainLayout); + + if (!report) { + m_report=new ReportEnginePrivate(this); + m_report->setObjectName("report"); + m_report->appendPage("page1"); + } + else { + m_report=report; + if (!m_report->pageCount()) m_report->appendPage("page1"); + } + + setActivePage(m_report->pageAt(0)); + foreach(QGraphicsItem* item, activePage()->selectedItems()){ + item->setSelected(false); + } + connect(m_report,SIGNAL(pagesLoadFinished()),this,SLOT(slotPagesLoadFinished())); + connect(m_report,SIGNAL(cleared()),this,SIGNAL(cleared())); + m_view->scale(0.5,0.5); + m_instance=this; +} + +ReportDesignWidget::~ReportDesignWidget() +{ m_instance=0;} + +void ReportDesignWidget::setActivePage(PageDesignIntf *page) +{ + m_view->setScene(page); + connect(page,SIGNAL(itemInserted(LimeReport::PageDesignIntf*,QPointF,QString)),this,SIGNAL(itemInserted(LimeReport::PageDesignIntf*,QPointF,QString))); + connect(page,SIGNAL(itemInsertCanceled(QString)),this,SIGNAL(itemInsertCanceled(QString))); + connect(page,SIGNAL(itemPropertyChanged(QString,QString,QVariant,QVariant)),this,SIGNAL(itemPropertyChanged(QString,QString,QVariant,QVariant))); + connect(page,SIGNAL(selectionChanged()),this,SLOT(slotSelectionChanged())); + connect(page,SIGNAL(insertModeStarted()),this,SIGNAL(insertModeStarted())); + connect(page,SIGNAL(commandHistoryChanged()),this,SIGNAL(commandHistoryChanged())); + connect(page,SIGNAL(sceneRectChanged(QRectF)),this,SLOT(slotSceneRectChanged(QRectF))); + + connect(page,SIGNAL(itemAdded(LimeReport::PageDesignIntf*,LimeReport::BaseDesignIntf*)), + this, SIGNAL(itemAdded(LimeReport::PageDesignIntf*,LimeReport::BaseDesignIntf*))); + connect(page,SIGNAL(itemRemoved(LimeReport::PageDesignIntf*,LimeReport::BaseDesignIntf*)), + this,SIGNAL(itemDeleted(LimeReport::PageDesignIntf*,LimeReport::BaseDesignIntf*))); + connect(page,SIGNAL(bandAdded(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*)), + this, SIGNAL(bandAdded(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*))); + connect(page, SIGNAL(bandRemoved(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*)), + this, SIGNAL(bandDeleted(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*))); + + + + m_view->centerOn(0, 0); + emit activePageChanged(); +} + +void ReportDesignWidget::createStartPage() +{ + PageDesignIntf* reportPage = m_report->appendPage("page1"); + setActivePage(reportPage); +} + +void ReportDesignWidget::removeDatasource(const QString &datasourceName) +{ + m_report->dataManager()->removeDatasource(datasourceName); +} + +void ReportDesignWidget::addBand(const QString &bandType) +{ + activePage()->addBand(bandType); +} + +void ReportDesignWidget::addBand(BandDesignIntf::BandsType bandType) +{ + activePage()->addBand(bandType); +} + +void ReportDesignWidget::startInsertMode(const QString &itemType) +{ + activePage()->startInsertMode(itemType); +} + +void ReportDesignWidget::startEditMode() +{ + activePage()->startEditMode(); +} + +PageDesignIntf * ReportDesignWidget::activePage() +{ + return qobject_cast(m_view->scene()); +} + +QList ReportDesignWidget::selectedItems(){ + return m_view->scene()->selectedItems(); +} + +void ReportDesignWidget::deleteItem(QGraphicsItem *item){ + activePage()->removeReportItem(dynamic_cast(item)); +} + +void ReportDesignWidget::deleteSelectedItems(){ + foreach(QGraphicsItem *item,activePage()->selectedItems()) deleteItem(item); +} + +QStringList ReportDesignWidget::datasourcesNames(){ + return m_report->dataManager()->dataSourceNames(); +} + +void ReportDesignWidget::slotItemSelected(BaseDesignIntf *item){ + emit itemSelected(item); +} + +void ReportDesignWidget::saveToFile(const QString &fileName){ + m_report->saveToFile(fileName); +} + +bool ReportDesignWidget::save() +{ + if (!m_report->reportFileName().isEmpty()){ + return m_report->saveToFile(); + } + else { + return m_report->saveToFile(QFileDialog::getSaveFileName(this,tr("Report file name"),"","Report files (*.lrxml);; All files (*)")); + } +} + +void ReportDesignWidget::loadFromFile(const QString &fileName) +{ + m_report->loadFromFile(fileName); + setActivePage(m_report->pageAt(0)); +} + +void ReportDesignWidget::scale(qreal sx, qreal sy) +{ + m_view->scale(sx,sy); +} + +QString ReportDesignWidget::reportFileName() +{ + return m_report->reportFileName(); +} + +bool ReportDesignWidget::isNeedToSave() +{ + return m_report->isNeedToSave(); +} + +void ReportDesignWidget::updateSize() +{ + activePage()->slotUpdateItemSize(); +} + +void ReportDesignWidget::undo() +{ + activePage()->undo(); +} + +void ReportDesignWidget::redo() +{ + activePage()->redo(); +} + +void ReportDesignWidget::copy() +{ + activePage()->copy(); +} + +void ReportDesignWidget::paste() +{ + activePage()->paste(); +} + +void ReportDesignWidget::cut() +{ + activePage()->cut(); +} + +void ReportDesignWidget::brinToFront() +{ + activePage()->bringToFront(); +} + +void ReportDesignWidget::sendToBack() +{ + activePage()->sendToBack(); +} + +void ReportDesignWidget::alignToLeft() +{ + activePage()->alignToLeft(); +} + +void ReportDesignWidget::alignToRight() +{ + activePage()->alignToRigth(); +} + +void ReportDesignWidget::alignToVCenter() +{ + activePage()->alignToVCenter(); +} + +void ReportDesignWidget::alignToTop() +{ + activePage()->alignToTop(); +} + +void ReportDesignWidget::alignToBottom() +{ + activePage()->alignToBottom(); +} + +void ReportDesignWidget::alignToHCenter() +{ + activePage()->alignToHCenter(); +} + +void ReportDesignWidget::sameHeight() +{ + activePage()->sameHeight(); +} + +void ReportDesignWidget::sameWidth() +{ + activePage()->sameWidth(); +} + +void ReportDesignWidget::editLayoutMode(bool value) +{ + if (value ){ + activePage()->pageItem()->setItemMode(activePage()->pageItem()->itemMode() | LayoutEditMode); + } else if (activePage()->pageItem()->itemMode() & LayoutEditMode){ + activePage()->pageItem()->setItemMode(activePage()->pageItem()->itemMode() ^ LayoutEditMode); + } +} + +void ReportDesignWidget::addHLayout() +{ + activePage()->addHLayout(); +} + +void ReportDesignWidget::setFont(const QFont& font) +{ + activePage()->setFont(font); +} + +void ReportDesignWidget::setTextAlign(const Qt::Alignment& alignment) +{ + activePage()->setTextAlign(alignment); +} + +void ReportDesignWidget::setBorders(const BaseDesignIntf::BorderLines& borders) +{ + activePage()->setBorders(borders); +} + +bool ReportDesignWidget::isCanUndo() +{ + return activePage()->isCanUndo(); +} + +bool ReportDesignWidget::isCanRedo() +{ + return activePage()->isCanRedo(); +} + +void ReportDesignWidget::slotSelectionChanged() +{ + QGraphicsScene* page=dynamic_cast(sender()); + if (page){ + if (page->selectedItems().count()==1){ + BaseDesignIntf* item = dynamic_cast(page->selectedItems().at(0)); + if (item) + emit (itemSelected(item)); + } + else if (page->selectedItems().count()>1){ + emit (multiItemSelected()); + } + } +} + +DataSourceManager* ReportDesignWidget::dataManager() +{ + return m_report->dataManager(); +} + +void ReportDesignWidget::slotPagesLoadFinished() +{ + setActivePage(m_report->pageAt(0)); + emit loaded(); +} + +void ReportDesignWidget::slotDatasourceCollectionLoaded(const QString & /*collectionName*/) +{ +} + +void ReportDesignWidget::slotSceneRectChanged(QRectF) +{ + m_view->centerOn(0,0); +} + +void ReportDesignWidget::clear() +{ + m_report->clearReport(); +} + +} + + + diff --git a/src/lrreportdesignwidget.h b/src/lrreportdesignwidget.h new file mode 100644 index 0000000..7154ad6 --- /dev/null +++ b/src/lrreportdesignwidget.h @@ -0,0 +1,135 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRREPORTDESIGNWIDGET_H +#define LRREPORTDESIGNWIDGET_H + +#include +#include +#include + +#include "lrpagedesignintf.h" +#include "lrdatadesignintf.h" +#include "lrdatasourcemanager.h" +#include "lrcollection.h" +#include "lrreportengine_p.h" + + +namespace LimeReport { + +class ReportEnginePrivate; +class DataBrowser; +class ReportDesignWindow; + +class ReportDesignWidget : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QObject* datasourcesManager READ dataManager()) + friend class ReportDesignWindow; +public: + ~ReportDesignWidget(); + static ReportDesignWidget* instance(){return m_instance;} + void createStartPage(); + void clear(); + DataSourceManager* dataManager(); + void removeDatasource(const QString& datasourceName); + void addBand(const QString& bandType); + void addBand(BandDesignIntf::BandsType bandType); + void startInsertMode(const QString& itemType); + void startEditMode(); + void updateSize(); + bool isCanUndo(); + bool isCanRedo(); + void deleteItem(QGraphicsItem *item); + PageDesignIntf* activePage(); + QList selectedItems(); + QStringList datasourcesNames(); + void scale( qreal sx, qreal sy); +// void setDatabrowser(DataBrowser* databrowser); + ReportEnginePrivate* report(){return m_report;} + QString reportFileName(); + bool isNeedToSave(); +public slots: + void saveToFile(const QString&); + bool save(); + void loadFromFile(const QString&); + void deleteSelectedItems(); + void setActivePage(PageDesignIntf* page); + void undo(); + void redo(); + void copy(); + void paste(); + void cut(); + void brinToFront(); + void sendToBack(); + void alignToLeft(); + void alignToRight(); + void alignToVCenter(); + void alignToTop(); + void alignToBottom(); + void alignToHCenter(); + void sameHeight(); + void sameWidth(); + void editLayoutMode(bool value); + void addHLayout(); + void setFont(const QFont &font); + void setTextAlign(const Qt::Alignment& alignment); + void setBorders(const BaseDesignIntf::BorderLines& borders); +private slots: + void slotItemSelected(LimeReport::BaseDesignIntf *item); + void slotSelectionChanged(); + void slotPagesLoadFinished(); + void slotDatasourceCollectionLoaded(const QString&); + void slotSceneRectChanged(QRectF); +signals: + void insertModeStarted(); + void itemInserted(LimeReport::PageDesignIntf*,QPointF,const QString&); + void itemInsertCanceled(const QString&); + void itemSelected(LimeReport::BaseDesignIntf *item); + void itemPropertyChanged(const QString& objectName, const QString& propertyName, const QVariant& oldValue, const QVariant& newValue); + void multiItemSelected(); + void commandHistoryChanged(); + void cleared(); + void loaded(); + void activePageChanged(); + void bandAdded(LimeReport::PageDesignIntf*, LimeReport::BandDesignIntf*); + void bandDeleted(LimeReport::PageDesignIntf*, LimeReport::BandDesignIntf*); + void itemAdded(LimeReport::PageDesignIntf*, LimeReport::BaseDesignIntf*); + void itemDeleted(LimeReport::PageDesignIntf*, LimeReport::BaseDesignIntf*); +private: + ReportDesignWidget(ReportEnginePrivate* report,QMainWindow *mainWindow,QWidget *parent = 0); +private: + ReportEnginePrivate* m_report; + QGraphicsView *m_view; + QMainWindow *m_mainWindow; + static ReportDesignWidget* m_instance; +}; + +} +#endif // LRREPORTDESIGNWIDGET_H diff --git a/src/lrreportdesignwindow.cpp b/src/lrreportdesignwindow.cpp new file mode 100644 index 0000000..89a5615 --- /dev/null +++ b/src/lrreportdesignwindow.cpp @@ -0,0 +1,908 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lrreportdesignwindow.h" +#include "lrbandsmanager.h" +#include "lrobjectinspectorwidget.h" +#include "lrbasedesignobjectmodel.h" +#include "lrreportdesignwidget.h" +#include "lrdatabrowser.h" +#include "lrbasedesignintf.h" +#include "lrpagedesignintf.h" + +#include "waitform.h" +#include "lrpreviewreportwindow.h" +#include "serializators/lrstorageintf.h" +#include "serializators/lrxmlreader.h" +#include "objectsbrowser/lrobjectbrowser.h" +#include "lraboutdialog.h" + + +namespace LimeReport{ + +ReportDesignWindow* ReportDesignWindow::m_instance=0; + +ReportDesignWindow::ReportDesignWindow(ReportEnginePrivate *report, QWidget *parent, QSettings* settings) : + QMainWindow(parent), m_textAttibutesIsChanging(false), m_settings(settings), m_ownedSettings(false), m_progressDialog(0), m_showProgressDialog(true) +{ + initReportEditor(report); + createActions(); + createMainMenu(); + createToolBars(); + createObjectInspector(); + createDataWindow(); + createObjectsBrowser(); + m_instance=this; + m_statusBar=new QStatusBar(this); + m_lblReportName = new QLabel(report->reportFileName(),this); + m_statusBar->insertWidget(0,m_lblReportName); + setStatusBar(m_statusBar); + setWindowTitle("Lime Report Designer"); + restoreSetting(); +} + +ReportDesignWindow::~ReportDesignWindow() +{ + m_instance=0; + delete m_validator; + if (m_ownedSettings&&m_settings) delete m_settings; +} + +void ReportDesignWindow::createActions() +{ + m_newReportAction = new QAction(tr("New Report"),this); + m_newReportAction->setIcon(QIcon(":/report/images/newReport")); + m_newReportAction->setShortcut(QKeySequence(Qt::CTRL+Qt::Key_N)); + connect(m_newReportAction,SIGNAL(triggered()),this,SLOT(slotNewReport())); + + m_editModeAction = new QAction(tr("Edit Mode"),this); + m_editModeAction->setIcon(QIcon(":/report/images/editMode")); + m_editModeAction->setCheckable(true); + m_editModeAction->setChecked(true); + connect(m_editModeAction,SIGNAL(triggered()),this,SLOT(slotEditMode())); + + m_undoAction = new QAction(tr("Undo"),this); + m_undoAction->setIcon(QIcon(":/report/images/undo")); + m_undoAction->setEnabled(false); + m_undoAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Z)); + connect(m_undoAction,SIGNAL(triggered()),this,SLOT(slotUndo())); + + m_redoAction = new QAction(tr("Redo"),this); + m_redoAction->setIcon(QIcon(":/report/images/redo")); + m_redoAction->setEnabled(false); + m_redoAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Z)); + connect(m_redoAction,SIGNAL(triggered()),this,SLOT(slotRedo())); + + m_copyAction = new QAction(tr("Copy"),this); + m_copyAction->setIcon(QIcon(":/report/images/copy")); + m_copyAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_C)); + connect(m_copyAction,SIGNAL(triggered()),this,SLOT(slotCopy())); + + m_pasteAction = new QAction(tr("Paste"),this); + m_pasteAction->setIcon(QIcon(":/report/images/paste")); + m_pasteAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_V)); + connect(m_pasteAction,SIGNAL(triggered()),this,SLOT(slotPaste())); + + m_cutAction = new QAction(tr("Cut"),this); + m_cutAction->setIcon(QIcon(":/report/images/cut")); + m_cutAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_X)); + connect(m_cutAction,SIGNAL(triggered()),this,SLOT(slotCut())); + + m_newTextItemAction = new QAction(tr("Text Item"),this); + m_newTextItemAction->setIcon(QIcon(":/items/TextItem")); + m_actionMap.insert("TextItem",m_newTextItemAction); + connect(m_newTextItemAction,SIGNAL(triggered()),this,SLOT(slotNewTextItem())); + + m_saveReportAction = new QAction(tr("Save Report"),this); + m_saveReportAction->setIcon(QIcon(":/report/images/save")); + m_saveReportAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_S)); + connect(m_saveReportAction,SIGNAL(triggered()),this,SLOT(slotSaveReport())); + + m_saveReportAsAction = new QAction(tr("Save Report As"),this); + m_saveReportAsAction->setIcon(QIcon(":/report/images/saveas")); + m_saveReportAsAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_S)); + connect(m_saveReportAsAction,SIGNAL(triggered()),this,SLOT(slotSaveReportAs())); + + m_loadReportAction = new QAction(tr("Load Report"),this); + m_loadReportAction->setIcon(QIcon(":/report/images/folder")); + m_loadReportAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_O)); + connect(m_loadReportAction,SIGNAL(triggered()),this,SLOT(slotLoadReport())); + + m_deleteItemAction = new QAction(tr("Delete item"),this); + m_deleteItemAction->setShortcut(QKeySequence("Del")); + m_deleteItemAction->setIcon(QIcon(":/report/images/delete")); + connect(m_deleteItemAction,SIGNAL(triggered()),this,SLOT(slotDelete())); + + m_zoomInReportAction = new QAction(tr("Zoom In"),this); + m_zoomInReportAction->setIcon(QIcon(":/report/images/zoomIn")); + connect(m_zoomInReportAction,SIGNAL(triggered()),this,SLOT(slotZoomIn())); + + m_zoomOutReportAction = new QAction(tr("Zoom Out"),this); + m_zoomOutReportAction->setIcon(QIcon(":/report/images/zoomOut")); + connect(m_zoomOutReportAction,SIGNAL(triggered()),this,SLOT(slotZoomOut())); + + m_previewReportAction = new QAction(tr("Render Report"),this); + m_previewReportAction->setIcon(QIcon(":/report/images/render")); + m_previewReportAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_P)); + connect(m_previewReportAction,SIGNAL(triggered()),this,SLOT(slotPreviewReport())); + + m_testAction = new QAction("test",this); + m_testAction->setIcon(QIcon(":/report/images/pin")); + connect(m_testAction,SIGNAL(triggered()),this,SLOT(slotTest())); + +// m_printReportAction = new QAction(tr("Print Report"),this); +// m_printReportAction->setIcon(QIcon(":/report/images/print")); +// m_printReportAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_P)); +// connect(m_printReportAction,SIGNAL(triggered()),this,SLOT(slotPrintReport())); + + m_editLayoutMode = new QAction(tr("Edit layouts mode"),this); + m_editLayoutMode->setIcon(QIcon(":/report/images/editlayout")); + m_editLayoutMode->setCheckable(true); + connect(m_editLayoutMode,SIGNAL(triggered()),this,SLOT(slotEditLayoutMode())); + + m_addHLayout = new QAction(tr("Horizontal layout"),this); + m_addHLayout->setIcon(QIcon(":/report/images/hlayout")); + connect(m_addHLayout,SIGNAL(triggered()),this,SLOT(slotHLayout())); + + m_aboutAction = new QAction(tr("About"),this); + m_aboutAction->setIcon(QIcon(":/report/images/copyright")); + connect(m_aboutAction,SIGNAL(triggered()),this,SLOT(slotShowAbout())); + +} + +void ReportDesignWindow::createReportToolBar() +{ + m_reportToolBar = new QToolBar(tr("Report Tools"),this); + m_reportToolBar->setIconSize(QSize(24,24)); + m_reportToolBar->addAction(m_editModeAction); + m_reportToolBar->addWidget(m_newBandButton); + m_reportToolBar->addAction(m_newTextItemAction); + m_reportToolBar->setObjectName("reportTools"); + createItemsActions(); + m_reportToolBar->addSeparator(); + //m_reportToolBar->addAction(m_editLayoutMode); + m_reportToolBar->addAction(m_addHLayout); + m_reportToolBar->addSeparator(); + m_reportToolBar->addAction(m_deleteItemAction); + addToolBar(Qt::LeftToolBarArea,m_reportToolBar); +} + +void ReportDesignWindow::createToolBars() +{ + createBandsButton(); + + m_mainToolBar = addToolBar("Main Tools"); + m_mainToolBar->setIconSize(QSize(16,16)); + m_mainToolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea | Qt::TopToolBarArea ); + m_mainToolBar->setFloatable(false); + m_mainToolBar->setObjectName("mainTools"); + + m_mainToolBar->addAction(m_newReportAction); + m_mainToolBar->addAction(m_saveReportAction); + m_mainToolBar->addAction(m_loadReportAction); + m_mainToolBar->addSeparator(); + + m_mainToolBar->addAction(m_copyAction); + m_mainToolBar->addAction(m_pasteAction); + m_mainToolBar->addAction(m_cutAction); + m_mainToolBar->addAction(m_undoAction); + m_mainToolBar->addAction(m_redoAction); + m_mainToolBar->addSeparator(); + + m_mainToolBar->addAction(m_zoomInReportAction); + m_mainToolBar->addAction(m_zoomOutReportAction); + m_mainToolBar->addSeparator(); + + m_mainToolBar->addAction(m_previewReportAction); + //m_mainToolBar->addAction(m_printReportAction); + + m_fontEditorBar = new FontEditorWidget(m_reportDesignWidget,tr("Font"),this); + m_fontEditorBar->setIconSize(m_mainToolBar->iconSize()); + m_fontEditorBar->setObjectName("fontTools"); + addToolBar(m_fontEditorBar); + m_textAlignmentEditorBar = new TextAlignmentEditorWidget(m_reportDesignWidget,tr("Text alignment"),this); + m_textAlignmentEditorBar->setIconSize(m_mainToolBar->iconSize()); + m_textAlignmentEditorBar->setObjectName("textAlignmentTools"); + addToolBar(m_textAlignmentEditorBar); + m_itemsAlignmentEditorBar = new ItemsAlignmentEditorWidget(m_reportDesignWidget,tr("Items alignment"),this); + m_itemsAlignmentEditorBar->setIconSize(m_mainToolBar->iconSize()); + m_itemsAlignmentEditorBar->setObjectName("itemsAlignmentTools"); + addToolBar(m_itemsAlignmentEditorBar); + m_itemsBordersEditorBar = new ItemsBordersEditorWidget(m_reportDesignWidget,tr("Borders"),this); + m_itemsBordersEditorBar->setIconSize(m_mainToolBar->iconSize()); + m_itemsBordersEditorBar->setObjectName("itemsBorederTools"); + addToolBar(m_itemsBordersEditorBar); + + createReportToolBar(); +} + +void ReportDesignWindow::createItemsActions() +{ + foreach(ItemAttribs items,DesignElementsFactory::instance().attribsMap().values()){ + if (items.m_tag.compare("Item",Qt::CaseInsensitive)==0){ + QAction* tmpAction = new QAction(items.m_alias,this); + tmpAction->setWhatsThis(DesignElementsFactory::instance().attribsMap().key(items)); + tmpAction->setIcon(QIcon(":/items/"+tmpAction->whatsThis())); + connect(tmpAction,SIGNAL(triggered()),this,SLOT(slotItemActionCliked())); + m_reportToolBar->addAction(tmpAction); + m_actionMap.insert(tmpAction->whatsThis(),tmpAction); + } + } +} + +void ReportDesignWindow::createBandsButton() +{ + m_newBandButton = new QToolButton(this); + m_newBandButton->setPopupMode(QToolButton::InstantPopup); + m_newBandButton->setIcon(QIcon(":/report/images/addBand")); + + m_bandsAddSignalsMap = new QSignalMapper(this); + + m_newReportHeader=new QAction(QIcon(),tr("Report Header"),this); + connect(m_newReportHeader,SIGNAL(triggered()),m_bandsAddSignalsMap,SLOT(map())); + m_bandsAddSignalsMap->setMapping(m_newReportHeader,BandDesignIntf::ReportHeader); + m_newBandButton->addAction(m_newReportHeader); + + m_newReportFooter=new QAction(QIcon(),tr("Report Footer"),this); + connect(m_newReportFooter,SIGNAL(triggered()),m_bandsAddSignalsMap,SLOT(map())); + m_bandsAddSignalsMap->setMapping(m_newReportFooter,BandDesignIntf::ReportFooter); + m_newBandButton->addAction(m_newReportFooter); + + m_newPageHeader=new QAction(QIcon(),tr("Page Header"),this); + connect(m_newPageHeader,SIGNAL(triggered()),m_bandsAddSignalsMap,SLOT(map())); + m_bandsAddSignalsMap->setMapping(m_newPageHeader,BandDesignIntf::PageHeader); + m_newBandButton->addAction(m_newPageHeader); + + m_newPageFooter=new QAction(QIcon(),tr("Page Footer"),this); + connect(m_newPageFooter,SIGNAL(triggered()),m_bandsAddSignalsMap,SLOT(map())); + m_bandsAddSignalsMap->setMapping(m_newPageFooter,BandDesignIntf::PageFooter); + m_newBandButton->addAction(m_newPageFooter); + + m_newData=new QAction(QIcon(),tr("Data"),this); + connect(m_newData,SIGNAL(triggered()),m_bandsAddSignalsMap,SLOT(map())); + m_bandsAddSignalsMap->setMapping(m_newData,BandDesignIntf::Data); + m_newBandButton->addAction(m_newData); + + m_newSubDetail=new QAction(QIcon(),tr("SubDetail"),this); + m_newSubDetail->setEnabled(false); + connect(m_newSubDetail,SIGNAL(triggered()),m_bandsAddSignalsMap,SLOT(map())); + m_bandsAddSignalsMap->setMapping(m_newSubDetail,BandDesignIntf::SubDetailBand); + m_newBandButton->addAction(m_newSubDetail); + + m_newSubDetailHeader=new QAction(QIcon(),tr("SubDetailHeader"),this); + m_newSubDetailHeader->setEnabled(false); + connect(m_newSubDetailHeader,SIGNAL(triggered()),m_bandsAddSignalsMap,SLOT(map())); + m_bandsAddSignalsMap->setMapping(m_newSubDetailHeader,BandDesignIntf::SubDetailHeader); + m_newBandButton->addAction(m_newSubDetailHeader); + + m_newSubDetailFooter=new QAction(QIcon(),tr("SubDetailFooter"),this); + m_newSubDetailFooter->setEnabled(false); + connect(m_newSubDetailFooter,SIGNAL(triggered()),m_bandsAddSignalsMap,SLOT(map())); + m_bandsAddSignalsMap->setMapping(m_newSubDetailFooter,BandDesignIntf::SubDetailFooter); + m_newBandButton->addAction(m_newSubDetailFooter); + + m_newGroupHeader=new QAction(QIcon(),tr("GroupHeader"),this); + m_newGroupHeader->setEnabled(false); + connect(m_newGroupHeader,SIGNAL(triggered()),m_bandsAddSignalsMap,SLOT(map())); + m_bandsAddSignalsMap->setMapping(m_newGroupHeader,BandDesignIntf::GroupHeader); + m_newBandButton->addAction(m_newGroupHeader); + + m_newGroupFooter=new QAction(QIcon(),tr("GroupFooter"),this); + m_newGroupFooter->setEnabled(false); + connect(m_newGroupFooter,SIGNAL(triggered()),m_bandsAddSignalsMap,SLOT(map())); + m_bandsAddSignalsMap->setMapping(m_newGroupFooter,BandDesignIntf::GroupFooter); + m_newBandButton->addAction(m_newGroupFooter); + + connect(m_bandsAddSignalsMap,SIGNAL(mapped(int)),this,SLOT(slotNewBand(int))); +} + +void ReportDesignWindow::createMainMenu() +{ + m_fileMenu = menuBar()->addMenu(tr("File")); + m_fileMenu->addAction(m_newReportAction); + m_fileMenu->addAction(m_loadReportAction); + m_fileMenu->addAction(m_saveReportAction); + m_fileMenu->addAction(m_saveReportAsAction); + m_fileMenu->addAction(m_previewReportAction); + //m_fileMenu->addAction(m_printReportAction); + m_editMenu = menuBar()->addMenu(tr("Edit")); + m_editMenu->addAction(m_redoAction); + m_editMenu->addAction(m_undoAction); + m_editMenu->addAction(m_copyAction); + m_editMenu->addAction(m_pasteAction); + m_editMenu->addAction(m_cutAction); + m_infoMenu = menuBar()->addMenu(tr("Info")); + m_infoMenu->addAction(m_aboutAction); + +} + +void ReportDesignWindow::initReportEditor(ReportEnginePrivate* report) +{ + m_reportDesignWidget=new ReportDesignWidget(report,this,this); + setCentralWidget(m_reportDesignWidget); + connect(m_reportDesignWidget, SIGNAL(itemSelected(LimeReport::BaseDesignIntf*)), + this, SLOT(slotItemSelected(LimeReport::BaseDesignIntf*))); + connect(m_reportDesignWidget, SIGNAL(itemPropertyChanged(QString,QString,QVariant,QVariant)), + this, SLOT(slotItemPropertyChanged(QString,QString,QVariant,QVariant))); + connect(m_reportDesignWidget, SIGNAL(insertModeStarted()), this, SLOT(slotInsertModeStarted())); + + connect(m_reportDesignWidget, SIGNAL(multiItemSelected()), this, SLOT(slotMultiItemSelected())); + connect(m_reportDesignWidget, SIGNAL(itemInserted(LimeReport::PageDesignIntf*,QPointF,QString)), + this, SLOT(slotItemInserted(LimeReport::PageDesignIntf*,QPointF,QString))); + connect(m_reportDesignWidget, SIGNAL(itemInsertCanceled(QString)), this, SLOT(slotItemInsertCanceled(QString))); + connect(m_reportDesignWidget->report(),SIGNAL(datasourceCollectionLoadFinished(QString)), this, SLOT(slotUpdateDataBrowser(QString))); + connect(m_reportDesignWidget, SIGNAL(commandHistoryChanged()),this,SLOT(slotCommandHistoryChanged())); + connect(m_reportDesignWidget, SIGNAL(bandAdded(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*)), + this, SLOT(slotBandAdded(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*))); + connect(m_reportDesignWidget, SIGNAL(bandDeleted(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*)), + this, SLOT(slotBandDeleted(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*))); + connect(m_reportDesignWidget->report(), SIGNAL(renderStarted()), this, SLOT(renderStarted())); + connect(m_reportDesignWidget->report(), SIGNAL(renderPageFinished(int)), this, SLOT(renderPageFinished(int))); + connect(m_reportDesignWidget->report(), SIGNAL(renderFinished()), this, SLOT(renderFinished())); +} + +void ReportDesignWindow::createObjectInspector() +{ + m_objectInspector = new ObjectInspectorWidget(this); + m_propertyModel = new BaseDesignPropertyModel(this); + m_validator = new ObjectNameValidator(); + m_propertyModel->setValidator(m_validator); + m_propertyModel->setSubclassesAsLevel(false); +// connect(m_propertyModel,SIGNAL(objectPropetyChanged(QString,QVariant,QVariant)),this,SLOT(slotItemDataChanged(QString,QVariant,QVariant))); + m_objectInspector->setModel(m_propertyModel); + m_objectInspector->setAlternatingRowColors(true); + m_objectInspector->setRootIsDecorated(!m_propertyModel->subclassesAsLevel()); + + QDockWidget *objectDoc = new QDockWidget(this); + QWidget* w = new QWidget(objectDoc); + QVBoxLayout* l = new QVBoxLayout(w); + l->addWidget(m_objectInspector); + l->setContentsMargins(2,2,2,2); + w->setLayout(l); + objectDoc->setWindowTitle(tr("Object Inspector")); + objectDoc->setWidget(w); + objectDoc->setObjectName("objectInspector"); + addDockWidget(Qt::LeftDockWidgetArea,objectDoc); +} + +void ReportDesignWindow::createObjectsBrowser() +{ + QDockWidget *doc = new QDockWidget(this); + doc->setWindowTitle(tr("Report structure")); + m_objectsBrowser = new ObjectBrowser(doc); + doc->setWidget(m_objectsBrowser); + doc->setObjectName("structureDoc"); + addDockWidget(Qt::RightDockWidgetArea,doc); + m_objectsBrowser->setMainWindow(this); + m_objectsBrowser->setReportEditor(m_reportDesignWidget); +} + +void ReportDesignWindow::createDataWindow() +{ + QDockWidget *dataDoc = new QDockWidget(this); + dataDoc->setWindowTitle(tr("Data Browser")); + m_dataBrowser=new DataBrowser(dataDoc); + dataDoc->setWidget(m_dataBrowser); + dataDoc->setObjectName("dataDoc"); + addDockWidget(Qt::LeftDockWidgetArea,dataDoc); + m_dataBrowser->setSettings(settings()); + m_dataBrowser->setMainWindow(this); + m_dataBrowser->setReportEditor(m_reportDesignWidget); +} + +void ReportDesignWindow::updateRedoUndo() +{ + m_undoAction->setEnabled(m_reportDesignWidget->isCanUndo()); + m_redoAction->setEnabled(m_reportDesignWidget->isCanRedo()); +} + +void ReportDesignWindow::startNewReport() +{ + m_reportDesignWidget->clear(); + m_reportDesignWidget->createStartPage(); + m_lblReportName->setText(""); + updateRedoUndo(); + m_newPageHeader->setEnabled(true); + m_newPageFooter->setEnabled(true); + m_newReportHeader->setEnabled(true); + m_newReportFooter->setEnabled(true); +} + +void ReportDesignWindow::writePosition() +{ + settings()->beginGroup("DesignerWindow"); + settings()->setValue("Geometry",saveGeometry()); + settings()->setValue("State",saveState()); + settings()->endGroup(); +} + +void ReportDesignWindow::writeState() +{ + settings()->beginGroup("DesignerWindow"); + settings()->setValue("State",saveState()); + settings()->setValue("InspectorFirsColumnWidth",m_objectInspector->columnWidth(0)); + settings()->endGroup(); +} + +void ReportDesignWindow::restoreSetting() +{ + settings()->beginGroup("DesignerWindow"); + QVariant v = settings()->value("Geometry"); + if (v.isValid()){ + restoreGeometry(v.toByteArray()); + } + v = settings()->value("State"); + if (v.isValid()){ + restoreState(v.toByteArray()); + } + v = settings()->value("InspectorFirsColumnWidth"); + if (v.isValid()){ + m_objectInspector->setColumnWidth(0,v.toInt()); + } + settings()->endGroup(); +} + +bool ReportDesignWindow::checkNeedToSave() +{ + if (m_reportDesignWidget->isNeedToSave()){ + QMessageBox::StandardButton button = QMessageBox::question( + this,"",tr("Report has been modified ! Do you want save the report ?"), + QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel, QMessageBox::Yes + ); + switch (button) { + case QMessageBox::Cancel: + break; + case QMessageBox::Yes: + if (!m_reportDesignWidget->save()) break; + default: + return true; + } + return false; + } + return true; +} + +void ReportDesignWindow::showModal() +{ + bool deleteOnClose = testAttribute(Qt::WA_DeleteOnClose); + setAttribute(Qt::WA_DeleteOnClose,false); + setAttribute(Qt::WA_ShowModal,true); + restoreSetting(); + show(); + m_eventLoop.exec(); + if (deleteOnClose) delete this; +} + +void ReportDesignWindow::showNonModal() +{ + restoreSetting(); + show(); +} + +void ReportDesignWindow::setSettings(QSettings* value) +{ + if (m_ownedSettings) + delete m_settings; + m_settings=value; + m_ownedSettings=false; + restoreSetting(); +} + +QSettings*ReportDesignWindow::settings() +{ + if (m_settings){ + return m_settings; + } else { + m_settings = new QSettings("LimeReport",QApplication::applicationName()); + m_ownedSettings = true; + return m_settings; + } +} + +void ReportDesignWindow::slotNewReport() +{ + if (checkNeedToSave()) startNewReport(); +} + +void ReportDesignWindow::slotNewTextItem() +{ + if (m_newTextItemAction->isChecked()) {m_newTextItemAction->setCheckable(false);return;} + if (m_reportDesignWidget) { + m_reportDesignWidget->startInsertMode("TextItem"); + m_newTextItemAction->setCheckable(true); + m_newTextItemAction->setChecked(true); + } +} + +void ReportDesignWindow::slotNewBand(const QString& bandType) +{ + if(m_reportDesignWidget) m_reportDesignWidget->addBand(bandType); +} + +void ReportDesignWindow::slotNewBand(int bandType) +{ + if(m_reportDesignWidget) m_reportDesignWidget->addBand(BandDesignIntf::BandsType(bandType)); +} + +void ReportDesignWindow::slotItemSelected(LimeReport::BaseDesignIntf *item) +{ + if (m_propertyModel->currentObject()!=item){ + + m_newSubDetail->setEnabled(false); + m_newSubDetailHeader->setEnabled(false); + m_newSubDetailFooter->setEnabled(false); + m_newGroupHeader->setEnabled(false); + m_newGroupFooter->setEnabled(false); + + m_objectInspector->commitActiveEditorData(); + m_propertyModel->setObject(item); + if (m_propertyModel->subclassesAsLevel()) + m_objectInspector->expandToDepth(0); + + QSet bs; + bs<(item); + if (band){ + if (bs.contains(band->bandType())){ + m_newSubDetail->setEnabled(true); + } + if ((band->bandType()==BandDesignIntf::Data)|| + (band->bandType()==BandDesignIntf::SubDetailBand) + ) + { + m_newGroupHeader->setEnabled(true); + } + if (band->bandType()==BandDesignIntf::GroupHeader){ + m_newGroupFooter->setEnabled(!band->isConnectedToBand(BandDesignIntf::GroupFooter)); + } + if (band->bandType()==BandDesignIntf::SubDetailBand){ + m_newSubDetailHeader->setEnabled(!band->isConnectedToBand(BandDesignIntf::SubDetailHeader)); + m_newSubDetailFooter->setEnabled(!band->isConnectedToBand(BandDesignIntf::SubDetailFooter)); + } + } + + m_fontEditorBar->setItem(item); + m_textAlignmentEditorBar->setItem(item); + m_itemsBordersEditorBar->setItem(item); + } +} + +void ReportDesignWindow::slotItemPropertyChanged(const QString &objectName, const QString &propertyName, const QVariant& oldValue, const QVariant& newValue ) +{ + Q_UNUSED(oldValue) + Q_UNUSED(newValue) + + if (m_propertyModel->currentObject()&&(m_propertyModel->currentObject()->objectName()==objectName)){ + m_propertyModel->updateProperty(propertyName); + } +} + +void ReportDesignWindow::slotMultiItemSelected() +{ + m_objectInspector->commitActiveEditorData(); + + QList selectionList; + foreach (QGraphicsItem* gi, m_reportDesignWidget->activePage()->selectedItems()) { + QObject* oi = dynamic_cast(gi); + if (oi) selectionList.append(oi); + } + m_propertyModel->setMultiObjects(&selectionList); + if (m_propertyModel->subclassesAsLevel()) + m_objectInspector->expandToDepth(0); +} + +void ReportDesignWindow::slotInsertModeStarted() +{ + m_editModeAction->setChecked(false); +} + +void ReportDesignWindow::slotItemInserted(PageDesignIntf *, QPointF, const QString &ItemType) +{ + m_editModeAction->setChecked(true); + if (m_actionMap.value(ItemType)) + m_actionMap.value(ItemType)->setCheckable(false); +} + +void ReportDesignWindow::slotItemInsertCanceled(const QString &ItemType) +{ + m_editModeAction->setChecked(true); + if (m_actionMap.value(ItemType)) + m_actionMap.value(ItemType)->setCheckable(false); +} + +void ReportDesignWindow::slotUpdateDataBrowser(const QString &collectionName) +{ + if (collectionName.compare("connections",Qt::CaseInsensitive)==0){ + if (m_dataBrowser) m_dataBrowser->initConnections(); + } + if (collectionName.compare("queries",Qt::CaseInsensitive)==0){ + if (m_dataBrowser) m_dataBrowser->updateDataTree(); + } + if (collectionName.compare("subqueries",Qt::CaseInsensitive)==0){ + if (m_dataBrowser) m_dataBrowser->updateDataTree(); + } + if (collectionName.compare("subproxies",Qt::CaseInsensitive)==0){ + if (m_dataBrowser) m_dataBrowser->updateDataTree(); + } + if (collectionName.compare("variables",Qt::CaseInsensitive)==0){ + if (m_dataBrowser) m_dataBrowser->updateVariablesTree(); + } +} + +void ReportDesignWindow::slotCommandHistoryChanged() +{ + updateRedoUndo(); +} + +void ReportDesignWindow::slotSaveReport() +{ + m_reportDesignWidget->save(); + m_lblReportName->setText(m_reportDesignWidget->reportFileName()); +} + +void ReportDesignWindow::slotSaveReportAs() +{ + QString fileName = QFileDialog::getSaveFileName(this,tr("Report file name"),"","Report files(*.lrxml);; All files(*)"); + if (!fileName.isEmpty()){ + m_reportDesignWidget->saveToFile(fileName); + m_lblReportName->setText(m_reportDesignWidget->reportFileName()); + } +} + +void ReportDesignWindow::slotLoadReport() +{ + if (checkNeedToSave()){ + QString fileName = QFileDialog::getOpenFileName(this,tr("Report file name"),"","Report files(*.lrxml);; All files(*)"); + if (!fileName.isEmpty()) { + QApplication::processEvents(); + setCursor(Qt::WaitCursor); + m_reportDesignWidget->clear(); + m_reportDesignWidget->loadFromFile(fileName); + m_lblReportName->setText(fileName); + m_propertyModel->setObject(0); + updateRedoUndo(); + unsetCursor(); + } + } +} + +void ReportDesignWindow::slotZoomIn() +{ + m_reportDesignWidget->scale(1.2,1.2); +} + +void ReportDesignWindow::slotZoomOut() +{ + m_reportDesignWidget->scale(1/1.2,1/1.2); +} + +void ReportDesignWindow::slotEditMode() +{ + m_editModeAction->setChecked(true); + m_reportDesignWidget->startEditMode(); +} + +void ReportDesignWindow::slotUndo() +{ + m_reportDesignWidget->undo(); + updateRedoUndo(); + +} + +void ReportDesignWindow::slotRedo() +{ + m_reportDesignWidget->redo(); + updateRedoUndo(); +} + +void ReportDesignWindow::slotCopy() +{ + m_reportDesignWidget->copy(); +} + +void ReportDesignWindow::slotPaste() +{ + m_reportDesignWidget->paste(); +} + +void ReportDesignWindow::slotCut() +{ + m_reportDesignWidget->cut(); +} + +void ReportDesignWindow::slotDelete() +{ + m_reportDesignWidget->deleteSelectedItems(); +} + +void ReportDesignWindow::slotEditLayoutMode() +{ + m_reportDesignWidget->editLayoutMode(m_editLayoutMode->isChecked()); +} + +void ReportDesignWindow::slotHLayout() +{ + m_reportDesignWidget->addHLayout(); +} + +void ReportDesignWindow::slotTest() +{ +} + +void ReportDesignWindow::slotPrintReport() +{ + setCursor(Qt::WaitCursor); + m_reportDesignWidget->report()->printReport(); + setCursor(Qt::ArrowCursor); +} + +void ReportDesignWindow::slotPreviewReport() +{ + m_reportDesignWidget->report()->previewReport(); +} + +void ReportDesignWindow::slotItemActionCliked() +{ + QAction* action=dynamic_cast(sender()); + action->setCheckable(true); + action->setChecked(true); + m_reportDesignWidget->startInsertMode(action->whatsThis()); +} + +void ReportDesignWindow::slotBandAdded(PageDesignIntf *, BandDesignIntf * band) +{ + if (band->isUnique()){ + switch (band->bandType()) { + case BandDesignIntf::PageHeader: + m_newPageHeader->setDisabled(true); + break; + case BandDesignIntf::PageFooter: + m_newPageFooter->setDisabled(true); + break; + case BandDesignIntf::ReportHeader: + m_newReportHeader->setDisabled(true); + break; + case BandDesignIntf::ReportFooter: + m_newReportFooter->setDisabled(true); + default: + break; + } + } +} + +void ReportDesignWindow::slotBandDeleted(PageDesignIntf *, BandDesignIntf *band) +{ + if (band->isUnique()){ + switch (band->bandType()) { + case BandDesignIntf::PageHeader: + m_newPageHeader->setEnabled(true); + break; + case BandDesignIntf::PageFooter: + m_newPageFooter->setEnabled(true); + break; + case BandDesignIntf::ReportHeader: + m_newReportHeader->setEnabled(true); + break; + case BandDesignIntf::ReportFooter: + m_newReportFooter->setEnabled(true); + default: + break; + } + } +} + +void ReportDesignWindow::renderStarted() +{ + if (m_showProgressDialog){ + m_progressDialog = new QProgressDialog(tr("Rendering report"),tr("Abort"),0,0,this); + m_progressDialog->open(m_reportDesignWidget->report(),SLOT(cancelRender())); + QApplication::processEvents(); + } +} + +void ReportDesignWindow::renderPageFinished(int renderedPageCount) +{ + if (m_progressDialog) + m_progressDialog->setLabelText(QString::number(renderedPageCount)+tr(" page rendered")); +} + +void ReportDesignWindow::renderFinished() +{ + if (m_progressDialog){ + m_progressDialog->close(); + delete m_progressDialog; + } + m_progressDialog = 0; +} + +void ReportDesignWindow::slotShowAbout() +{ + AboutDialog* about = new AboutDialog(this); + about->exec(); +} + +void ReportDesignWindow::closeEvent(QCloseEvent * event) +{ + if (checkNeedToSave()){ + m_dataBrowser->closeAllDataWindows(); + writeState(); +#ifdef Q_OS_WIN + writePosition(); +#endif +#ifdef Q_OS_MAC + writePosition(); +#endif + m_eventLoop.exit(); + event->accept(); + } else event->ignore(); +} + +void ReportDesignWindow::resizeEvent(QResizeEvent*) +{ +#ifdef Q_OS_UNIX + writePosition(); +#endif +} + +void ReportDesignWindow::moveEvent(QMoveEvent*) +{ +#ifdef Q_OS_UNIX + writePosition(); +#endif +} + +bool ObjectNameValidator::validate(const QString &propName, const QVariant &propValue, QObject *object, QString &msg) +{ + if (propName.compare("objectName")==0){ + BaseDesignIntf* bd = dynamic_cast(object); + if (bd){ + if (bd->page()->reportItemByName(propValue.toString())){ + msg = QString(QObject::tr("Object with name %1 already exists").arg(propValue.toString())); + return false; + } else (bd->emitObjectNamePropertyChanged(object->objectName(),propValue.toString())); + } + } + return true; +} + +} + diff --git a/src/lrreportdesignwindow.h b/src/lrreportdesignwindow.h new file mode 100644 index 0000000..2c0c490 --- /dev/null +++ b/src/lrreportdesignwindow.h @@ -0,0 +1,213 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRREPORTEDITORWINDOW_H +#define LRREPORTEDITORWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include "lrbanddesignintf.h" +#include "items/editors/lrfonteditorwidget.h" +#include "items/editors/lrtextalignmenteditorwidget.h" +#include "items/editors/lritemsaligneditorwidget.h" +#include "items/editors/lritemsborderseditorwidget.h" +#include "lrobjectitemmodel.h" + +namespace LimeReport{ + +class ObjectInspectorWidget; +class QObjectPropertyModel; +class ReportDesignWidget; +class DataBrowser; +class BaseDesignIntf; +class PageDesignIntf; +class ObjectBrowser; + +class ReportDesignWindow : public QMainWindow +{ + Q_OBJECT +public: + explicit ReportDesignWindow(ReportEnginePrivate* report, QWidget *parent = 0, QSettings* settings=0); + ~ReportDesignWindow(); + static ReportDesignWindow* instance(){return m_instance;} + + bool checkNeedToSave(); + void showModal(); + void showNonModal(); + void setSettings(QSettings* value); + QSettings* settings(); + void restoreSetting(); + void setShowProgressDialog(bool value){m_showProgressDialog = value;} + +private slots: + void slotNewReport(); + void slotNewTextItem(); + void slotNewBand(const QString& bandType); + void slotNewBand(int bandType); + void slotSaveReport(); + void slotSaveReportAs(); + void slotLoadReport(); + void slotZoomIn(); + void slotZoomOut(); + void slotEditMode(); + void slotUndo(); + void slotRedo(); + void slotCopy(); + void slotPaste(); + void slotCut(); + void slotDelete(); + void slotEditLayoutMode(); + void slotHLayout(); + void slotItemSelected(LimeReport::BaseDesignIntf *item); + void slotItemPropertyChanged(const QString& objectName, const QString& propertyName, const QVariant &oldValue, const QVariant &newValue); + void slotMultiItemSelected(); + void slotInsertModeStarted(); + void slotItemInserted(LimeReport::PageDesignIntf* , QPointF, const QString& ItemType); + void slotItemInsertCanceled(const QString& ItemType); + void slotUpdateDataBrowser(const QString& collectionName); + void slotCommandHistoryChanged(); + void slotTest(); + void slotPrintReport(); + void slotPreviewReport(); + void slotItemActionCliked(); + void slotBandAdded(LimeReport::PageDesignIntf*, LimeReport::BandDesignIntf*band); + void slotBandDeleted(LimeReport::PageDesignIntf*, LimeReport::BandDesignIntf*band); + void renderStarted(); + void renderPageFinished(int renderedPageCount); + void renderFinished(); + void slotShowAbout(); +protected: + void closeEvent(QCloseEvent *event); + void resizeEvent(QResizeEvent *); + void moveEvent(QMoveEvent *); +private: + void createActions(); + void createBandsButton(); + void createMainMenu(); + void createToolBars(); + void createReportToolBar(); + void createItemsActions(); + void createObjectInspector(); + void createObjectsBrowser(); + void initReportEditor(ReportEnginePrivate* report); + void createDataWindow(); + void updateRedoUndo(); + void startNewReport(); + void writePosition(); + void writeState(); + +private: + static ReportDesignWindow* m_instance; + + QStatusBar* m_statusBar; + QToolBar* m_mainToolBar; + QToolBar* m_fontToolBar; + QToolBar* m_reportToolBar; + QToolBar* m_alignToolBar; + QToolButton* m_newBandButton; + QMenuBar* m_mainMenu; + QMenu* m_fileMenu; + QMenu* m_editMenu; + QMenu* m_infoMenu; + + QAction* m_newReportAction; + QAction* m_newTextItemAction; + QAction* m_deleteItemAction; + QAction* m_saveReportAction; + QAction* m_saveReportAsAction; + QAction* m_loadReportAction; + QAction* m_zoomInReportAction; + QAction* m_zoomOutReportAction; + QAction* m_previewReportAction; + QAction* m_closeRenderViewAction; + QAction* m_nextPageAction; + QAction* m_priorPageAction; + QAction* m_testAction; + QAction* m_printReportAction; + QAction* m_editModeAction; + QAction* m_undoAction; + QAction* m_redoAction; + QAction* m_copyAction; + QAction* m_pasteAction; + QAction* m_cutAction; + + QAction* m_newPageHeader; + QAction* m_newPageFooter; + QAction* m_newReportHeader; + QAction* m_newReportFooter; + QAction* m_newData; + QAction* m_newSubDetail; + QAction* m_newSubDetailHeader; + QAction* m_newSubDetailFooter; + QAction* m_newGroupHeader; + QAction* m_newGroupFooter; + QAction* m_aboutAction; + QAction* m_editLayoutMode; + QAction* m_addHLayout; + + QSignalMapper* m_bandsAddSignalsMap; + + ObjectInspectorWidget* m_objectInspector; + QObjectPropertyModel* m_propertyModel; + + ReportDesignWidget* m_reportDesignWidget; + DataBrowser * m_dataBrowser; + + ObjectBrowser* m_objectsBrowser; + + QHash m_actionMap; + QLabel* m_lblReportName; + QEventLoop m_eventLoop; + QFontComboBox* m_fontNameEditor; + QComboBox* m_fontSizeEditor; + QStringListModel m_fontSizeModel; + bool m_textAttibutesIsChanging; + BaseDesignIntf const * m_fontItem; + FontEditorWidget* m_fontEditorBar; + TextAlignmentEditorWidget* m_textAlignmentEditorBar; + ItemsAlignmentEditorWidget* m_itemsAlignmentEditorBar; + ItemsBordersEditorWidget* m_itemsBordersEditorBar; + QSettings* m_settings; + bool m_ownedSettings; + ValidatorIntf* m_validator; + QProgressDialog* m_progressDialog; + bool m_showProgressDialog; +}; + +class ObjectNameValidator : public ValidatorIntf{ + bool validate(const QString &propName, const QVariant &propValue, QObject *object, QString &msg); +}; + +} +#endif // LRREPORTEDITORWINDOW_H diff --git a/src/lrreportengine.cpp b/src/lrreportengine.cpp new file mode 100644 index 0000000..728b498 --- /dev/null +++ b/src/lrreportengine.cpp @@ -0,0 +1,587 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include +#include +#include +#include +#include + +#include "time.h" + +#include "lrreportengine_p.h" +#include "lrreportengine.h" + +#include "lrpagedesignintf.h" +#include "lrdatasourcemanager.h" +#include "lrdatabrowser.h" +#include "lrreportdesignwindow.h" + +#include "serializators/lrxmlwriter.h" +#include "serializators/lrxmlreader.h" +#include "lrreportrender.h" +#include "lrpreviewreportwindow.h" + +namespace LimeReport{ + +QSettings* ReportEngine::m_settings = 0; + +ReportEnginePrivate::ReportEnginePrivate(QObject *parent) : + QObject(parent), m_fileName(""), m_settings(0), m_ownedSettings(false), + m_printer(new QPrinter(QPrinter::HighResolution)), m_printerSelected(false), m_showProgressDialog(true) +{ + m_datasources= new DataSourceManager(this); + m_datasources->setObjectName("datasources"); + //m_reportRender=ReportRender::Ptr(new ReportRender()); + //m_reportRender->setDatasources(m_datasources); + connect(m_datasources,SIGNAL(loadCollectionFinished(QString)),this,SLOT(slotDataSourceCollectionLoaded(QString))); +} + +ReportEnginePrivate::~ReportEnginePrivate() +{ + foreach(PageDesignIntf* page,m_pages) delete page; + m_pages.clear(); + if (m_ownedSettings&&m_settings) delete m_settings; +} + +QObject* ReportEnginePrivate::createElement(const QString &, const QString &) +{ + return appendPage(); +} + +QObject *ReportEnginePrivate::elementAt(const QString &, int index) +{ + return pageAt(index); +} + +PageDesignIntf *ReportEnginePrivate::createPage(const QString &pageName) +{ + PageDesignIntf* page =new PageDesignIntf(this); + page->setObjectName(pageName); + page->setReportEditor(this); + //m_pages.append(page); + return page; +} + +PageDesignIntf *ReportEnginePrivate::appendPage(const QString &pageName) +{ + PageDesignIntf* page = createPage(pageName); + m_pages.append(page); + return page; +} + +PageDesignIntf *ReportEnginePrivate::createPreviewPage() +{ + return createPage(); +} + +int ReportEnginePrivate::elementsCount(const QString &) +{ + return m_pages.count(); +} + +void ReportEnginePrivate::collectionLoadFinished(const QString &) +{ + foreach (PageDesignIntf* page, m_pages) { + page->setReportEditor(this); + page->setSceneRect(-SCENE_MARGIN,-SCENE_MARGIN, + page->pageItem()->width()+SCENE_MARGIN*2, + page->pageItem()->height()+SCENE_MARGIN*2); + } + emit pagesLoadFinished(); +} + +void ReportEnginePrivate::saveError(QString message) +{ + m_lastError = message; +} + +void ReportEnginePrivate::showError(QString message) +{ + QMessageBox::critical(0,tr("Error"),message); +} + +void ReportEnginePrivate::slotDataSourceCollectionLoaded(const QString &collectionName) +{ + emit datasourceCollectionLoadFinished(collectionName); +} + +void ReportEnginePrivate::clearReport() +{ + foreach(PageDesignIntf* page,m_pages) delete page; + m_pages.clear(); + m_datasources->clear(DataSourceManager::Owned); + m_fileName=""; + emit cleared(); +} + +void ReportEnginePrivate::printReport(ItemsReaderIntf::Ptr reader, QPrinter& printer) +{ + LimeReport::PageDesignIntf renderPage; + renderPage.setItemMode(PrintMode); + if (reader->first()){ + reader->readItem(renderPage.pageItem()); + printer.setPageMargins(renderPage.pageItem()->leftMargin(), + renderPage.pageItem()->topMargin(), + renderPage.pageItem()->rightMargin(), + renderPage.pageItem()->bottomMargin(), + QPrinter::Millimeter); + printer.setOrientation((QPrinter::Orientation)renderPage.pageItem()->pageOrientation()); + renderPage.setSceneRect(renderPage.pageItem()->mapToScene(renderPage.pageItem()->rect()).boundingRect()); + + QSizeF pageSize = (renderPage.pageItem()->pageOrientation()==PageItemDesignIntf::Landscape)? + QSizeF(renderPage.pageItem()->sizeMM().height(),renderPage.pageItem()->sizeMM().width()): + renderPage.pageItem()->sizeMM(); + printer.setPaperSize(pageSize,QPrinter::Millimeter); + + QPainter painter(&printer); + renderPage.render(&painter); + + while (reader->next()){ + printer.newPage(); + renderPage.removeAllItems(); + reader->readItem(renderPage.pageItem()); + renderPage.setSceneRect(renderPage.pageItem()->mapToScene(renderPage.pageItem()->rect()).boundingRect()); + renderPage.render(&painter); + } + } +} + +void ReportEnginePrivate::printReport(ReportPages pages, QPrinter &printer, const PrintRange& printRange) +{ + LimeReport::PageDesignIntf renderPage; + renderPage.setItemMode(PrintMode); + QPainter* painter=0; + + bool isFirst = true; + int currenPage = 1; + foreach(PageItemDesignIntf::Ptr page,pages){ + + if ( + (printRange.rangeType()==QPrintDialog::AllPages) || + ( (printRange.rangeType()==QPrintDialog::PageRange) && + (currenPage>=printRange.fromPage()) && + (currenPage<=printRange.toPage()) + ) + ) + { + + QPointF pagePos = page->pos(); + page->setPos(0,0); + renderPage.setPageItem(page); + + renderPage.setSceneRect(renderPage.pageItem()->mapToScene(renderPage.pageItem()->rect()).boundingRect()); + printer.setPageMargins(renderPage.pageItem()->leftMargin(), + renderPage.pageItem()->topMargin(), + renderPage.pageItem()->rightMargin(), + renderPage.pageItem()->bottomMargin(), + QPrinter::Millimeter); + printer.setOrientation((QPrinter::Orientation)renderPage.pageItem()->pageOrientation()); + + QSizeF pageSize = (renderPage.pageItem()->pageOrientation()==PageItemDesignIntf::Landscape)? + QSizeF(renderPage.pageItem()->sizeMM().height(),renderPage.pageItem()->sizeMM().width()): + renderPage.pageItem()->sizeMM(); + printer.setPaperSize(pageSize,QPrinter::Millimeter); + + if (!isFirst){ + printer.newPage(); + } else { + isFirst=false; + painter = new QPainter(&printer); + } + + renderPage.render(painter); + page->setPos(pagePos); + } + + currenPage++; + } + if (painter) delete painter; + +} + +bool ReportEnginePrivate::printReport(QPrinter* printer) +{ + //QScopedPointerl_printer(new QPrinter(QPrinter::HighResolution)); + if (!printer&&!m_printerSelected){ + QPrintDialog dialog(m_printer.data(),QApplication::activeWindow()); + m_printerSelected = dialog.exec()!=QDialog::Rejected; + } + if (!printer&&!m_printerSelected) return false; + + printer =(printer)?printer:m_printer.data(); + if (printer&&printer->isValid()){ + try{ + dataManager()->setDesignTime(false); + printReport(renderToPages(),*printer,PrintRange()); + dataManager()->setDesignTime(true); + } catch(ReportError &exception){ + saveError(exception.what()); + } + return true; + } else return false; +} + +void ReportEnginePrivate::printToFile(const QString &fileName) +{ + if (!fileName.isEmpty()){ + QFile file(fileName); + if (file.open(QIODevice::WriteOnly)){ + QTextStream out(&file); + try { + dataManager()->setDesignTime(false); + out<setDesignTime(true); + } catch( ReportError &exception){ + saveError(exception.what()); + } + } + file.close(); + } +} + +void ReportEnginePrivate::previewReport() +{ + QTime start = QTime::currentTime(); + try{ + dataManager()->setDesignTime(false); + ReportPages pages = renderToPages(); + dataManager()->setDesignTime(true); + if (pages.count()>0){ + PreviewReportWindow* w = new PreviewReportWindow(this,QApplication::activeWindow(),settings()); + w->setWindowFlags(Qt::Dialog|Qt::WindowMaximizeButtonHint|Qt::WindowCloseButtonHint); + w->setAttribute(Qt::WA_DeleteOnClose,true); + w->setWindowModality(Qt::ApplicationModal); + w->setWindowIcon(QIcon(":/report/images/main.ico")); + w->setSettings(settings()); + w->setPages(pages); + if (!dataManager()->errorsList().isEmpty()){ + w->setErrorMessages(dataManager()->errorsList()); + } + qDebug()<<"render time ="<exec(); + } + } catch (ReportError &exception){ + saveError(exception.what()); + showError(exception.what()); + } +} + +PageDesignIntf* ReportEnginePrivate::createPreviewScene(QObject* parent){ + PageDesignIntf* result = 0; + try { + ReportPages pages = renderToPages(); + result = new PageDesignIntf(parent); + result->setPageItems(pages); + } catch (ReportError &exception){ + saveError(exception.what()); + showError(exception.what()); + } + return result; +} + +void ReportEnginePrivate::cancelRender() +{ + if (m_reportRender) + m_reportRender->cancelRender(); +} + +//PageDesignIntf* ReportEngine::createPreviewScene(QObject* parent){ +// Q_D(ReportEngine); +// return d->createPreviewScene(parent); +//} + +void ReportEnginePrivate::designReport() +{ + LimeReport::ReportDesignWindow* w = new LimeReport::ReportDesignWindow(this,QApplication::activeWindow(),settings()); + w->setAttribute(Qt::WA_DeleteOnClose,true); + w->setWindowIcon(QIcon(":report/images/main")); + w->setShowProgressDialog(m_showProgressDialog); +#if defined(Q_OS_MAC) + //w->showModal(); +#elif defined(Q_OS_UNIX) + //w->showModal(); +#endif +#ifdef Q_OS_WIN + w->setWindowFlags(Qt::Window|Qt::WindowMaximizeButtonHint|Qt::WindowCloseButtonHint); + w->setWindowModality(Qt::ApplicationModal); + //w->showModal(); +#endif + if (QApplication::activeWindow()==0){ + w->show(); + } else { + w->showModal(); + } +} + +void ReportEnginePrivate::setSettings(QSettings* value) +{ + if (value){ + if (m_ownedSettings&&m_settings) + delete m_settings; + m_settings = value; + m_ownedSettings = false; + } +} + +QSettings*ReportEnginePrivate::settings() +{ + if (m_settings){ + return m_settings; + } else { + m_settings = new QSettings("LimeReport",QApplication::applicationName()); + m_ownedSettings=true; + return m_settings; + } +} + +bool ReportEnginePrivate::loadFromFile(const QString &fileName) +{ + clearReport(); + //QScopedPointer< ItemsReaderIntf > reader(new FileXMLReader(fileName)); + ItemsReaderIntf::Ptr reader = FileXMLReader::create(fileName); + if (reader->first()){ + if (reader->readItem(this)){ + m_fileName=fileName; + return true; + }; + } + return false; +} + +bool ReportEnginePrivate::loadFromByteArray(QByteArray* data){ + clearReport(); + ItemsReaderIntf::Ptr reader = ByteArrayXMLReader::create(data); + if (reader->first()){ + if (reader->readItem(this)){ + m_fileName=""; + return true; + }; + } + return false; +} + +bool ReportEnginePrivate::saveToFile(const QString &fileName) +{ + if (fileName.isEmpty()) return false; + QFileInfo fi(fileName); + QString fn = fileName; + if (fi.suffix().isEmpty()) + fn+=".lrxml"; + + QScopedPointer< ItemsWriterIntf > writer(new XMLWriter()); + writer->putItem(this); + m_fileName=fn; + bool saved = writer->saveToFile(fn); + if (saved){ + foreach(PageDesignIntf* page, m_pages){ + page->setToSaved(); + } + } + return saved; +} + +bool ReportEnginePrivate::isNeedToSave() +{ + foreach(PageDesignIntf* page, m_pages){ + if (page->isHasChanges()) return true; + } + return false; +} + +bool ReportEnginePrivate::saveToFile() +{ + if (m_fileName.isEmpty()) return false; + return saveToFile(m_fileName); +} + +QString ReportEnginePrivate::renderToString() +{ + LimeReport::ReportRender render; + dataManager()->connectAllDatabases(); + dataManager()->setDesignTime(false); + if (m_pages.count()){ + render.setDatasources(dataManager()); + return render.renderPageToString(m_pages.at(0)); + }else return QString(); +} + +ReportPages ReportEnginePrivate::renderToPages() +{ + + //ReportRender render; + m_reportRender = ReportRender::Ptr(new ReportRender); + dataManager()->clearErrorsList(); + dataManager()->connectAllDatabases(); + dataManager()->setDesignTime(false); + connect(m_reportRender.data(),SIGNAL(pageRendered(int)), + this, SIGNAL(renderPageFinished(int))); + if (m_pages.count()){ + emit renderStarted(); + m_reportRender->setDatasources(dataManager()); + ReportPages result = m_reportRender->renderPageToPages(m_pages.at(0)); + emit renderFinished(); + return result; + }else return ReportPages(); + m_reportRender.clear(); +} + +QString ReportEnginePrivate::lastError() +{ + return m_lastError; +} + +ReportEngine::ReportEngine(QObject *parent) + : QObject(parent), d_ptr(new ReportEnginePrivate()) +{ + Q_D(ReportEngine); + d->q_ptr=this; + connect(d, SIGNAL(renderStarted()), this, SIGNAL(renderStarted())); + connect(d, SIGNAL(renderPageFinished(int)), + this, SIGNAL(renderPageFinished(int))); + connect(d, SIGNAL(renderFinished()), this, SIGNAL(renderFinished())); +} + +ReportEngine::~ReportEngine() +{ + if (d_ptr) delete d_ptr; +} + +bool ReportEngine::printReport(QPrinter *printer) +{ + Q_D(ReportEngine); + return d->printReport(printer); +} + +//void ReportEngine::printReport(ReportPages pages, QPrinter &printer){ +// Q_D(ReportEngine); +// d->printReport(pages,printer,PrintRange()); +//} + +void ReportEngine::printToFile(const QString &fileName) +{ + Q_D(ReportEngine); + d->printToFile(fileName); +} + +void ReportEngine::previewReport() +{ + Q_D(ReportEngine); + if (m_settings) + d->setSettings(m_settings); + d->previewReport(); +} + +void ReportEngine::designReport() +{ + Q_D(ReportEngine); + if (m_settings) + d->setSettings(m_settings); + d->designReport(); +} + +void ReportEngine::setShowProgressDialog(bool value) +{ + Q_D(ReportEngine); + d->setShowProgressDialog(value); +} + +IDataSourceManager *ReportEngine::dataManager() +{ + Q_D(ReportEngine); + return d->dataManagerIntf(); +} + +IScriptEngineManager* ReportEngine::scriptManager() +{ + Q_D(ReportEngine); + return d->scriptManagerIntf(); +} + +bool ReportEngine::loadFromFile(const QString &fileName) +{ + Q_D(ReportEngine); + return d->loadFromFile(fileName); +} + +bool ReportEngine::loadFromByteArray(QByteArray* data){ + Q_D(ReportEngine); + return d->loadFromByteArray(data); +} + +QString ReportEngine::reportFileName() +{ + Q_D(ReportEngine); + return d->reportFileName(); +} + +//void ReportDesignIntf::setPrinter(QPrinter *printer) +//{ +// Q_D(ReportDesignIntf); +// d->setPrinter(printer); +//} + +bool ReportEngine::saveToFile() +{ + Q_D(ReportEngine); + return d->saveToFile(); +} + +bool ReportEngine::saveToFile(const QString &fileName) +{ + Q_D(ReportEngine); + return d->saveToFile(fileName); +} + +QString ReportEngine::lastError() +{ + Q_D(ReportEngine); + return d->lastError(); +} + +void ReportEngine::cancelRender() +{ + Q_D(ReportEngine); + d->cancelRender(); +} + +ReportEngine::ReportEngine(ReportEnginePrivate &dd, QObject *parent) + :QObject(parent),d_ptr(&dd) +{ + Q_D(ReportEngine); + d->q_ptr=this; + connect(d, SIGNAL(renderStarted()), this, SIGNAL(renderStarted())); + connect(d, SIGNAL(renderPageFinished(int)), + this, SIGNAL(renderPageFinished(int))); + connect(d, SIGNAL(renderFinished()), this, SIGNAL(renderFinished())); +} + + + +} diff --git a/src/lrreportengine.h b/src/lrreportengine.h new file mode 100644 index 0000000..924976a --- /dev/null +++ b/src/lrreportengine.h @@ -0,0 +1,105 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRREPORTDESIGNINTF_H +#define LRREPORTDESIGNINTF_H + +#include +#include +#include + +#include "lrglobal.h" +#include "lrdatasourcemanagerintf.h" +#include "lrscriptenginemanagerintf.h" +//#include "lrreportrender.h" + +class QPrinter; + +namespace LimeReport { + + +class PrintRange{ +public: + int fromPage() const { return m_fromPage;} + int toPage() const { return m_toPage;} + QPrintDialog::PrintRange rangeType() const { return m_rangeType;} + PrintRange(QAbstractPrintDialog::PrintRange rangeType=QPrintDialog::AllPages, int fromPage=0, int toPage=0); + void setRangeType(QAbstractPrintDialog::PrintRange rangeType){ m_rangeType=rangeType;} + void setFromPage(int fromPage){ m_fromPage = fromPage;} + void setToPage(int toPage){ m_toPage = toPage;} +private: + QPrintDialog::PrintRange m_rangeType; + int m_fromPage; + int m_toPage; +}; + +class DataSourceManager; +class ReportEnginePrivate; +//class PageDesignIntf; + +class LIMEREPORT_EXPORT ReportEngine : public QObject{ + Q_OBJECT +public: + static void setSettings(QSettings *value){m_settings=value;} +public: + explicit ReportEngine(QObject *parent = 0); + ~ReportEngine(); + bool printReport(QPrinter *printer=0); + //void printReport(ReportPages pages, QPrinter &printer); + void printToFile(const QString& fileName); + //PageDesignIntf *createPreviewScene(QObject *parent = 0); + void previewReport(); + void designReport(); + void setShowProgressDialog(bool value); + IDataSourceManager* dataManager(); + IScriptEngineManager* scriptManager(); + + bool loadFromFile(const QString& fileName); + bool loadFromByteArray(QByteArray *data); + QString reportFileName(); + bool saveToFile(); + bool saveToFile(const QString& fileName); + QString lastError(); +signals: + void renderStarted(); + void renderFinished(); + void renderPageFinished(int renderedPageCount); +public slots: + void cancelRender(); +protected: + ReportEnginePrivate * const d_ptr; + ReportEngine(ReportEnginePrivate &dd, QObject * parent=0); +private: + Q_DECLARE_PRIVATE(ReportEngine) + static QSettings* m_settings; +}; + +} // namespace LimeReport + +#endif // LRREPORTDESIGNINTF_H diff --git a/src/lrreportengine_p.h b/src/lrreportengine_p.h new file mode 100644 index 0000000..6e67427 --- /dev/null +++ b/src/lrreportengine_p.h @@ -0,0 +1,126 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRREPORTDESIGNINTF_P_H +#define LRREPORTDESIGNINTF_P_H + +#include +#include +#include "lrreportengine.h" +#include "lrcollection.h" +#include "lrglobal.h" +#include "lrdatasourcemanager.h" +#include "lrbanddesignintf.h" +#include "lrreportrender.h" +#include "serializators/lrstorageintf.h" +#include "lrscriptenginemanager.h" + +namespace LimeReport{ + +class PageDesignIntf; +class PrintRange; + +//TODO: Add on render callback + +class ReportEnginePrivate : public QObject, public ICollectionContainer +{ + Q_OBJECT + Q_DECLARE_PUBLIC(ReportEngine) + Q_PROPERTY(ACollectionProperty pages READ fakeCollectionReader()) + Q_PROPERTY(QObject* datasourcesManager READ dataManager()) +public: + static void printReport(ItemsReaderIntf::Ptr reader, QPrinter &printer); + static void printReport(ReportPages pages, QPrinter &printer, const PrintRange &printRange); +public: + explicit ReportEnginePrivate(QObject *parent = 0); + virtual ~ReportEnginePrivate(); + PageDesignIntf* appendPage(const QString &pageName = ""); + PageDesignIntf* createPreviewPage(); + PageDesignIntf* pageAt(int index){return (index<=(m_pages.count()-1)) ? m_pages.at(index):0;} + int pageCount() {return m_pages.count();} + DataSourceManager* dataManager(){return m_datasources;} + IDataSourceManager* dataManagerIntf(){return m_datasources;} + IScriptEngineManager* scriptManagerIntf(){return &ScriptEngineManager::instance();} + + void clearReport(); + bool printReport(QPrinter *printer=0); + void printToFile(const QString& fileName); + void previewReport(); + void designReport(); + void setSettings(QSettings* value); + void setShowProgressDialog(bool value){m_showProgressDialog = value;} + QSettings* settings(); + bool loadFromFile(const QString& fileName); + bool loadFromByteArray(QByteArray *data); + QString reportFileName(){return m_fileName;} + bool saveToFile(); + bool saveToFile(const QString& fileName); + bool isNeedToSave(); + QString lastError(); + ReportEngine * q_ptr; + PageDesignIntf *createPreviewScene(QObject *parent); +signals: + void pagesLoadFinished(); + void datasourceCollectionLoadFinished(const QString& collectionName); + void cleared(); + void renderStarted(); + void renderFinished(); + void renderPageFinished(int renderedPageCount); +public slots: + void cancelRender(); +protected: + PageDesignIntf* createPage(const QString& pageName=""); +protected slots: + void slotDataSourceCollectionLoaded(const QString& collectionName); +private: + //ICollectionContainer + virtual QObject* createElement(const QString&,const QString&); + virtual int elementsCount(const QString&); + virtual QObject* elementAt(const QString&, int index); + virtual void collectionLoadFinished(const QString&); + void saveError(QString message); + void showError(QString message); + //ICollectionContainer + ReportPages renderToPages(); + QString renderToString(); +private: + QList m_pages; + DataSourceManager* m_datasources; + ReportRender::Ptr m_reportRender; + QString m_fileName; + QString m_lastError; + QSettings* m_settings; + bool m_ownedSettings; + QScopedPointer m_printer; + bool m_printerSelected; + bool m_showProgressDialog; +}; + +} +#endif // LRREPORTDESIGNINTF_P_H diff --git a/src/lrreportrender.cpp b/src/lrreportrender.cpp new file mode 100644 index 0000000..b79a6a4 --- /dev/null +++ b/src/lrreportrender.cpp @@ -0,0 +1,680 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include +#include +#include + +#include "lrreportrender.h" +#include "lrpagedesignintf.h" +#include "lrbanddesignintf.h" +#include "lritemdesignintf.h" +#include "lrscriptenginemanager.h" + +#include "serializators/lrxmlreader.h" +#include "serializators/lrxmlwriter.h" + +namespace LimeReport{ + +ReportRender::ReportRender(QObject *parent) + :QObject(parent), m_renderPageItem(0), m_pageCount(0) +{} + +void ReportRender::setDatasources(DataSourceManager *value) +{ + m_datasources=value; +} + +void ReportRender::renderPage(PageDesignIntf* patternPage) +{ + m_patternPageItem=patternPage->pageItem(); + m_pageCount=1; + m_renderCanceled = false; + BandDesignIntf* reportFooter = m_patternPageItem->bandByType(BandDesignIntf::ReportFooter); + if (reportFooter) + m_reportFooterHeight = reportFooter->height(); + + initVariables(); + initGroupFunctions(); + + clearPageMap(); + + try{ + datasources()->setAllDatasourcesToFirst(); + } catch(ReportError &exception){ + //TODO posible should thow exeption + QMessageBox::critical(0,tr("Error"),exception.what()); + return; + } + + startNewPage(); + + renderBand(m_patternPageItem->bandByType(BandDesignIntf::ReportHeader),StartNewPage); + + BandDesignIntf* lastRenderedBand = 0; + for (int i=0;idataBandCount() && !m_renderCanceled;i++){ + lastRenderedBand = m_patternPageItem->dataBandAt(i); + renderDataBand(lastRenderedBand); + if (idataBandCount()-1) closeFooterGroup(lastRenderedBand); + } + + if (reportFooter) + renderBand(reportFooter,StartNewPage); + if (lastRenderedBand && lastRenderedBand->keepFooterTogether()) + closeFooterGroup(lastRenderedBand); + + savePage(); + if (!m_renderCanceled) + secondRenderPass(); +} + +int ReportRender::pageCount() +{ + return m_renderedPages.count(); +} + +PageItemDesignIntf::Ptr ReportRender::pageAt(int index) +{ + if ((index>m_renderedPages.count()-1)||(index<0)) throw ReportError("page index out of range"); + else return m_renderedPages.at(index); +} + +QString ReportRender::renderPageToString(PageDesignIntf *patternPage) +{ + renderPage(patternPage); + return toString(); +} + +ReportPages ReportRender::renderPageToPages(PageDesignIntf *patternPage) +{ + renderPage(patternPage); + return m_renderedPages; +} + +void ReportRender::initRenderPage() +{ + if (!m_renderPageItem) { + m_renderPageItem = new PageItemDesignIntf(m_patternPageItem->pageSize(), m_patternPageItem->pageRect()); + m_renderPageItem->initFromItem(m_patternPageItem); + } +} + +void ReportRender::initVariables() +{ + m_datasources->setReportVariable("#PAGE",1); + m_datasources->setReportVariable("#PAGE_COUNT",0); +} + +void ReportRender::clearPageMap() +{ + m_renderedPages.clear(); +} + +void ReportRender::extractGroupsFunction(BandDesignIntf *band) +{ + foreach(BaseDesignIntf* item,band->childBaseItems()){ + ContentItemDesignIntf* contentItem = dynamic_cast(item); + if (contentItem&&(contentItem->content().contains(QRegExp("\\$S\\s*\\{.*\\}")))){ + foreach(QString functionName, DataSourceManager::instance()->groupFunctionNames()){ + QRegExp rx(QString(GROUP_FUNCTION_RX).arg(functionName)); + QRegExp rxName(QString(GROUP_FUNCTION_NAME_RX).arg(functionName)); + if (rx.indexIn(contentItem->content())>=0){ + BandDesignIntf* dataBand = m_patternPageItem->bandByName(rx.cap(DATASOURCE_INDEX)); + if (dataBand){ + GroupFunction* gf = datasources()->addGroupFunction(functionName,rx.cap(VALUE_INDEX),band->objectName(),dataBand->objectName()); + if (gf){ + connect(dataBand,SIGNAL(bandRendered(BandDesignIntf*)),gf,SLOT(slotBandRendered(BandDesignIntf*))); + } + } else { + GroupFunction* gf = datasources()->addGroupFunction(functionName,rx.cap(VALUE_INDEX),band->objectName(),rx.cap(DATASOURCE_INDEX)); + gf->setInvalid(tr("Databand \"%1\" not found").arg(rx.cap(DATASOURCE_INDEX))); + } + } else if (rxName.indexIn(contentItem->content())>=0){ + GroupFunction* gf = datasources()->addGroupFunction(functionName,rxName.cap(1),band->objectName(),""); + gf->setInvalid(tr("Wrong using function %1").arg(functionName)); + } + } + } + } +} + +void ReportRender::replaceGroupsFunction(BandDesignIntf *band) +{ + foreach(BaseDesignIntf* item,band->childBaseItems()){ + ContentItemDesignIntf* contentItem = dynamic_cast(item); + if (contentItem){ + QString content = contentItem->content(); + foreach(QString functionName, DataSourceManager::instance()->groupFunctionNames()){ + QRegExp rx(QString(GROUP_FUNCTION_RX).arg(functionName)); + if (rx.indexIn(content)>=0){ + content.replace(rx,QString("%1(%2,%3)").arg(functionName).arg('"'+rx.cap(4)+'"').arg('"'+band->objectName()+'"')); + contentItem->setContent(content); + } + } + } + } +} + +void ReportRender::renderBand(BandDesignIntf *patternBand, ReportRender::DataRenderMode mode, bool isLast) +{ + QApplication::processEvents(); + if (patternBand){ + BandDesignIntf* bandClone=renderData(patternBand); + patternBand->emitBandRendered(bandClone); + + if ( isLast && bandClone->keepFooterTogether() && bandClone->sliceLastRow() ){ + if (m_currentMaxHeight < (bandClone->height()+m_reportFooterHeight)) + m_currentMaxHeight -= ((m_currentMaxHeight-bandClone->height())+(bandClone->height()*calcSlicePercent(bandClone->height()))); + } + + if (!bandClone->isEmpty() || patternBand->printIfEmpty()){ + if (!registerBand(bandClone)){ + if (bandClone->canBeSplitted(m_currentMaxHeight)){ + bandClone = sliceBand(bandClone,patternBand,isLast); + } else { + + qreal percent = (bandClone->height()-m_currentMaxHeight)/(bandClone->height()/100); + if (bandClone->maxScalePercent()>=percent){ + if (percentmaxScalePercent()){ + percent += 2; + bandClone->setScale((100-percent)/100); + bandClone->setHeight(m_currentMaxHeight); + registerBand(bandClone); + } + } else { + + if (mode==StartNewPage){ + savePage(); + startNewPage(); + if (!registerBand(bandClone)) { + bandClone->setHeight(m_currentMaxHeight); + registerBand(bandClone); + }; + } + + else { + bandClone->setHeight(m_currentMaxHeight); + registerBand(bandClone); + } + } + } + } + } + if (patternBand->isFooter()) + datasources()->clearGroupFunctionValues(patternBand->objectName()); + } +} + +void ReportRender::renderDataBand(BandDesignIntf *dataBand) +{ + IDataSource* bandDatasource = 0; + if (dataBand) + bandDatasource = datasources()->dataSource(dataBand->datasourceName()); + if(bandDatasource && !bandDatasource->eof() && !m_renderCanceled){ + QString varName = QLatin1String("line_")+dataBand->objectName().toLower(); + datasources()->setReportVariable(varName,1); + renderChildHeader(dataBand,PrintNotAlwaysPrintable); + renderGroupHeader(dataBand,bandDatasource); + while(!bandDatasource->eof() && !m_renderCanceled){ + + if (dataBand->tryToKeepTogether()) openDataGroup(dataBand); + + if (dataBand->keepFooterTogether() && !bandDatasource->hasNext()) + openFooterGroup(dataBand); + + datasources()->updateChildrenData(dataBand->datasourceName()); + m_lastDataBand = dataBand; + renderBand(dataBand,StartNewPage,!bandDatasource->hasNext()); + renderChildBands(dataBand); + + bandDatasource->next(); + + datasources()->setReportVariable(varName,datasources()->variable(varName).toInt()+1); + renderGroupHeader(dataBand,bandDatasource); + if (dataBand->tryToKeepTogether()) closeDataGroup(dataBand); + } + + renderGroupFooter(dataBand); + renderChildFooter(dataBand,PrintNotAlwaysPrintable); + datasources()->deleteVariable(varName); + } else if (bandDatasource==0) { + renderBand(dataBand,StartNewPage); + } +} + +void ReportRender::renderPageHeader(PageItemDesignIntf *patternPage) +{ + BandDesignIntf* band = patternPage->bandByType(BandDesignIntf::PageHeader); + if (band) renderBand(band); +} + +void ReportRender::renderPageFooter(PageItemDesignIntf *patternPage) +{ + BandDesignIntf* band = patternPage->bandByType(BandDesignIntf::PageFooter); + if (band){ + BandDesignIntf* bandClone = dynamic_cast(band->cloneItem(PreviewMode, m_renderPageItem,m_renderPageItem)); + replaceGroupsFunction(bandClone); + bandClone->updateItemSize(); + bandClone->setItemPos(m_patternPageItem->pageRect().x(),m_patternPageItem->pageRect().bottom()-bandClone->height()); + bandClone->setHeight(m_pageFooterHeight); + m_currentMaxHeight+=m_pageFooterHeight; + registerBand(bandClone); + datasources()->clearGroupFunctionValues(band->objectName()); + } +} + +void ReportRender::renderPageItems(PageItemDesignIntf* patternPage) +{ + foreach (BaseDesignIntf* item, patternPage->childBaseItems()) { + ItemDesignIntf* id = dynamic_cast(item); + if (id&&id->itemLocation()==ItemDesignIntf::Page){ + BaseDesignIntf* cloneItem = item->cloneItem(m_renderPageItem->itemMode(), + m_renderPageItem, + m_renderPageItem); + cloneItem->updateItemSize(); + } + } +} + +qreal ReportRender::calcPageFooterHeight(PageItemDesignIntf *patternPage) +{ + BandDesignIntf* band = patternPage->bandByType(BandDesignIntf::PageFooter); + if (band){ + return band->height(); + } + return 0; +} + +void ReportRender::renderChildHeader(BandDesignIntf *parent, BandPrintMode printMode) +{ + foreach(BandDesignIntf* band,parent->childrenByType(BandDesignIntf::SubDetailHeader)){ + bool printAlways=false; + if (band->metaObject()->indexOfProperty("printAlways")>0){ + printAlways=band->property("printAlways").toBool(); + } + if (printAlways == (printMode==PrintAlwaysPrintable) ) renderBand(band,StartNewPage); + } +} + +void ReportRender::renderChildFooter(BandDesignIntf *parent, BandPrintMode printMode) +{ + foreach(BandDesignIntf* band,parent->childrenByType(BandDesignIntf::SubDetailFooter)){ + bool printAlways=false; + if (band->metaObject()->indexOfProperty("printAlways")>0){ + printAlways=band->property("printAlways").toBool(); + } + if (printAlways == (printMode==PrintAlwaysPrintable)) renderBand(band,StartNewPage); + } +} + +void ReportRender::renderChildBands(BandDesignIntf *parentBand) +{ + foreach(BandDesignIntf* band,parentBand->childrenByType(BandDesignIntf::SubDetailBand)){ + IDataSource* ds = m_datasources->dataSource(band->datasourceName()); + if (ds) ds->first(); + renderChildHeader(band,PrintAlwaysPrintable); + renderDataBand(band); + renderChildFooter(band,PrintAlwaysPrintable); + closeFooterGroup(band); + } +} + +void ReportRender::renderGroupHeader(BandDesignIntf *parentBand, IDataSource* dataSource) +{ + foreach(BandDesignIntf* band,parentBand->childrenByType(BandDesignIntf::GroupHeader)){ + IGropBand* gb = dynamic_cast(band); + if (gb&&gb->isNeedToClose()){ + if (band->childBands().count()>0){ + dataSource->prior(); + renderBand(band->childBands().at(0),StartNewPage); + dataSource->next(); + } + closeDataGroup(band); + } + if (!gb->isStarted()){ + gb->startGroup(); + openDataGroup(band); + renderBand(band,StartNewPage); + } + } +} + +void ReportRender::renderGroupFooter(BandDesignIntf *parentBand) +{ + foreach(BandDesignIntf* band,parentBand->childrenByType(BandDesignIntf::GroupHeader)){ + IGropBand* gb = dynamic_cast(band); + if (gb->isStarted()){ + if (band->childBands().count()>0){ + renderBand(band->childBands().at(0),StartNewPage); + } + closeDataGroup(band); + } + } +} + +void ReportRender::initGroupFunctions() +{ + m_datasources->clearGroupFunction(); + foreach(BandDesignIntf* band, m_patternPageItem->childBands()){ + if (band->isFooter()) extractGroupsFunction(band); + } +} + +void ReportRender::popPageFooterGroupValues(BandDesignIntf *dataBand) +{ + BandDesignIntf* pageFooter = m_patternPageItem->bandByType(BandDesignIntf::PageFooter); + if (pageFooter){ + foreach(GroupFunction* gf, datasources()->groupFunctionsByBand(pageFooter->objectName())){ + if ((gf->dataBandName()==dataBand->objectName())){ + // FIXME Probably coincidence Field and Variables + if ((!m_popupedExpression.contains(dataBand))||(!m_popupedExpression.values(dataBand).contains(gf->data()))){ + m_popupedExpression.insert(dataBand,gf->data()); + m_popupedValues.insert(QString::number((long)dataBand,16)+'|'+gf->data(), gf->values()[gf->values().count()-1]); + gf->values().pop_back(); + } + } + } + } +} + +void ReportRender::pushPageFooterGroupValues(BandDesignIntf *dataBand) +{ + BandDesignIntf* pageFooter = m_patternPageItem->bandByType(BandDesignIntf::PageFooter); + if (pageFooter){ + foreach(GroupFunction* gf, datasources()->groupFunctionsByBand(pageFooter->objectName())){ + if ((gf->dataBandName()==dataBand->objectName())){ + // FIXME Probably coincidence Field and Variables + if ((m_popupedExpression.contains(dataBand))&&(m_popupedExpression.values(dataBand).contains(gf->data()))){ + gf->values().push_back(m_popupedValues.value(QString::number((long)dataBand,16)+'|'+gf->data())); + } + } + } + } +} + +void ReportRender::closeGroup(BandDesignIntf *band) +{ + QMultiMap< BandDesignIntf*, GroupBandsHolder* >::iterator it; + it = m_childBands.find(band); + + while (it!=m_childBands.end()&&it.key()==band){ + GroupBandsHolder* bl = it.value(); + if (bl){ + bl->clear(); + delete bl; + } + it++; + } + + m_childBands.remove(band); +} + +void ReportRender::openDataGroup(BandDesignIntf *band) +{ + m_childBands.insert(band,new GroupBandsHolder(band->tryToKeepTogether())); +} + +void ReportRender::openFooterGroup(BandDesignIntf *band) +{ + GroupBandsHolder* holder = new GroupBandsHolder(true); + holder->setIsFooterGroup(); + m_childBands.insert(band,holder); +} + +void ReportRender::closeDataGroup(BandDesignIntf *band) +{ + IGropBand* groupBand = dynamic_cast(band); + if (groupBand) + groupBand->closeGroup(); + closeGroup(band); +} + +void ReportRender::closeFooterGroup(BandDesignIntf *band){ + closeGroup(band); +} + +bool ReportRender::registerBand(BandDesignIntf *band, bool registerInChildren) +{ + if (band->height()<=m_currentMaxHeight){ + m_currentMaxHeight-=band->height(); + if (band->bandType()!=BandDesignIntf::PageFooter){ + band->setPos(m_renderPageItem->pageRect().x(),m_currentStartDataPos); + m_currentStartDataPos+=band->height(); + band->setBandIndex(++m_currentIndex); + } + + m_renderPageItem->registerBand(band); + + foreach(QList* list,m_childBands.values()){ + if (registerInChildren && + band->bandType()!=BandDesignIntf::PageHeader && + band->bandType()!=BandDesignIntf::PageFooter && + band->bandType()!=BandDesignIntf::ReportHeader && + band->bandType()!=BandDesignIntf::ReportFooter && + !list->contains(band) + ) + list->append(band); + } + if (band->isData()) m_renderedDataBandCount++; + return true; + } else return false; +} + +qreal ReportRender::calcSlicePercent(qreal height){ + return (height*3/(m_dataAreaSize))/100; +} + +BandDesignIntf* ReportRender::sliceBand(BandDesignIntf *band, BandDesignIntf* patternBand, bool isLast) +{ + while (band->height()>m_currentMaxHeight) { + band = saveUppperPartReturnBottom(band,m_currentMaxHeight,patternBand); + if (!band->isEmpty()) { + band->setHeight(0); + band->updateItemSize(); + DataBandDesignIntf* data = dynamic_cast(band); + if (isLast && data && data->keepFooterTogether() && + band->height()sliceLastRow() + ){ + if (band->height()>(m_currentMaxHeight-m_reportFooterHeight)){ + m_currentMaxHeight -= ((m_currentMaxHeight-band->height())+(band->height()*calcSlicePercent(band->height()))); + } + } + if (registerBand(band)) break; + } + } + + if (band->isEmpty()) { + delete band; + band = 0; + + } + + return band; + +} + +void ReportRender::secondRenderPass() +{ + foreach(PageItemDesignIntf::Ptr page, m_renderedPages){ + foreach(BandDesignIntf* band, page->childBands()){ + band->updateItemSize(SecondPass); + } + } +} + +BandDesignIntf *ReportRender::saveUppperPartReturnBottom(BandDesignIntf *band, int height, BandDesignIntf* patternBand) +{ + int sliceHeight = height; + BandDesignIntf* upperBandPart = dynamic_cast(band->cloneUpperPart(sliceHeight)); + BandDesignIntf* bottomBandPart = dynamic_cast(band->cloneBottomPart(sliceHeight)); + if (!bottomBandPart->isEmpty()){ + //bottomBandPart->updateItemSize(FirstPass,height); + if (patternBand->keepFooterTogether()) + closeFooterGroup(patternBand); + } + if (!upperBandPart->isEmpty()){ + upperBandPart->updateItemSize(FirstPass,height); + registerBand(upperBandPart); + } else delete upperBandPart; + savePage(); + startNewPage(); + if (!bottomBandPart->isEmpty() && patternBand->keepFooterTogether()) + openFooterGroup(patternBand); + delete band; + return bottomBandPart; +} + +BandDesignIntf *ReportRender::renderData(BandDesignIntf *patternBand) +{ + BandDesignIntf* bandClone = dynamic_cast(patternBand->cloneItem(PreviewMode)); + if (patternBand->isFooter()){ + replaceGroupsFunction(bandClone); + } + bandClone->updateItemSize(); + return bandClone; +} + +void ReportRender::startNewPage() +{ + m_renderPageItem=0; + + initRenderPage(); + + m_renderPageItem->setObjectName(QLatin1String("ReportPage")+QString::number(m_pageCount)); + m_currentMaxHeight=m_renderPageItem->pageRect().height(); + + m_currentStartDataPos=m_patternPageItem->topMargin()*mmFACTOR; + m_currentIndex=0; + + renderPageHeader(m_patternPageItem); + m_pageFooterHeight = calcPageFooterHeight(m_patternPageItem); + m_currentMaxHeight -= m_pageFooterHeight; + m_currentIndex=10; + m_dataAreaSize = m_currentMaxHeight; + m_renderedDataBandCount = 0; + + pasteGroups(); + renderPageItems(m_patternPageItem); +} + +void ReportRender::cutGroups() +{ + m_popupedExpression.clear(); + m_popupedValues.clear(); + foreach(BandDesignIntf* groupBand,m_childBands.keys()){ + if (m_childBands.value(groupBand)->tryToKeepTogether()){ + foreach(BandDesignIntf* band, *m_childBands.value(groupBand)){ + m_renderPageItem->removeBand(band); + popPageFooterGroupValues(band); + band->setParent(0); + band->setParentItem(0); + } + } + } + +} + +void ReportRender::checkFooterGroup(BandDesignIntf *groupBand) +{ + if (m_childBands.contains(groupBand)){ + GroupBandsHolder* holder = m_childBands.value(groupBand); + foreach(BandDesignIntf* band, *holder){ + qreal percent = band->height()*100 / m_dataAreaSize; + if (m_renderedDataBandCount<=1 || percent>20 ){ + holder->removeAll(band); + } + } + } +} + +void ReportRender::pasteGroups() +{ + BandDesignIntf* groupBand = findEnclosingGroup(); + if (groupBand){ + foreach(BandDesignIntf* band, *m_childBands.value(groupBand)){ + registerBand(band,false); + if (band->isData()) m_renderedDataBandCount++; + pushPageFooterGroupValues(band); + } + foreach(GroupBandsHolder* holder, m_childBands.values()) + holder->setTryToKeepTogether(false); + } + m_popupedExpression.clear(); + m_popupedValues.clear(); +} + +BandDesignIntf* ReportRender::findEnclosingGroup() +{ + BandDesignIntf* result=0; + int groupIndex = -1; + if (!m_childBands.isEmpty()){ + foreach(BandDesignIntf* gb, m_childBands.keys()){ + if (m_childBands.value(gb)->tryToKeepTogether()&& + ((gb->bandIndex()bandIndex(); + } + } + } + return result; +} + +void ReportRender::savePage() +{ + checkFooterGroup(m_lastDataBand); + cutGroups(); + renderPageFooter(m_patternPageItem); + m_pageCount++; + m_datasources->setReportVariable("#PAGE",m_pageCount); + m_datasources->setReportVariable("#PAGE_COUNT",m_pageCount-1); + BandDesignIntf* pageFooter = m_renderPageItem->bandByType(BandDesignIntf::PageFooter); + if (pageFooter) pageFooter->setBandIndex(++m_currentIndex); + m_renderedPages.append(PageItemDesignIntf::Ptr(m_renderPageItem)); + emit pageRendered(m_pageCount); +} + +QString ReportRender::toString() +{ + QScopedPointer writer(new XMLWriter()); + foreach(PageItemDesignIntf::Ptr page,m_renderedPages){ + writer->putItem(page.data()); + } + return writer->saveToString(); +} + +ReportRender::~ReportRender(){ + m_renderedPages.clear(); +} + +void ReportRender::cancelRender(){ + m_renderCanceled = true; +} + +} diff --git a/src/lrreportrender.h b/src/lrreportrender.h new file mode 100644 index 0000000..6dd385f --- /dev/null +++ b/src/lrreportrender.h @@ -0,0 +1,151 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRREPORTRENDER_H +#define LRREPORTRENDER_H +#include +#include "lrcollection.h" +#include "lrdatasourcemanager.h" +#include "lrpageitemdesignintf.h" +#include "serializators/lrstorageintf.h" + +namespace LimeReport{ + +class PageDesignIntf; +class BandDesignIntf; + +class GroupBandsHolder: public QList{ +public: + GroupBandsHolder(bool tryToKeepTogether):QList(),m_tryToKeepTogether(tryToKeepTogether), + m_dataGroup(true), m_footerGroup(false){} + bool tryToKeepTogether(){return m_tryToKeepTogether;} + void setTryToKeepTogether(bool value){m_tryToKeepTogether=value;} + bool isDataGroup(){return m_dataGroup;} + bool isFooterGroup(){ return m_footerGroup;} + void setIsFooterGroup(){m_footerGroup=true;m_dataGroup=false;} +private: + bool m_tryToKeepTogether; + bool m_dataGroup; + bool m_footerGroup; +}; + +typedef QList ReportPages; + +class ReportRender: public QObject +{ + Q_OBJECT + Q_PROPERTY(QObject* datasourcesManager READ datasources()) +public: + enum DataRenderMode {StartNewPage,NotStartNewPage}; + enum BandPrintMode {PrintAlwaysPrintable, PrintNotAlwaysPrintable }; + typedef QSharedPointer Ptr; + ~ReportRender(); + ReportRender(QObject *parent = 0); + void setDatasources(DataSourceManager* value); + DataSourceManager* datasources(){return m_datasources;} + void renderPage(PageDesignIntf *patternPage); + int pageCount(); + PageItemDesignIntf::Ptr pageAt(int index); + QString renderPageToString(PageDesignIntf *patternPage); + ReportPages renderPageToPages(PageDesignIntf *patternPage); +signals: + void pageRendered(int renderedPageCount); +public slots: + void cancelRender(); +private: + void initRenderPage(); + void initVariables(); + void clearPageMap(); + void renderBand(BandDesignIntf *patternBand, DataRenderMode mode = NotStartNewPage, bool isLast = false); + void renderDataBand(BandDesignIntf* dataBand); + void renderPageHeader(PageItemDesignIntf* patternPage); + void renderPageFooter(PageItemDesignIntf* patternPage); + void renderPageItems(PageItemDesignIntf* patternPage); + qreal calcPageFooterHeight(PageItemDesignIntf* patternPage); + qreal calcSlicePercent(qreal height); + void renderChildHeader(BandDesignIntf* parent, BandPrintMode printMode); + void renderChildFooter(BandDesignIntf* parent, BandPrintMode printMode); + void renderChildBands(BandDesignIntf* parentBand); + void renderGroupHeader(BandDesignIntf* parentBand, IDataSource* dataSource); + void renderGroupFooter(BandDesignIntf* parentBand); + + void initGroupFunctions(); + void extractGroupsFunction(BandDesignIntf* band); + void replaceGroupsFunction(BandDesignIntf* band); + + void popPageFooterGroupValues(BandDesignIntf* dataBand); + void pushPageFooterGroupValues(BandDesignIntf* dataBand); + + enum GroupType{DATA,FOOTER}; + void closeGroup(BandDesignIntf* band); + void openDataGroup(BandDesignIntf* band); + void closeDataGroup(BandDesignIntf* band); + void openFooterGroup(BandDesignIntf* band); + void closeFooterGroup(BandDesignIntf* band); + void cutGroups(); + void checkFooterGroup(BandDesignIntf* groupBand); + void pasteGroups(); + + BandDesignIntf* findEnclosingGroup(); + bool registerBand(BandDesignIntf* band, bool registerInChildren=true); + BandDesignIntf *sliceBand(BandDesignIntf* band, BandDesignIntf *patternBand, bool isLast); + void secondRenderPass(); + BandDesignIntf* saveUppperPartReturnBottom(BandDesignIntf *band, int height, BandDesignIntf *patternBand); + BandDesignIntf* renderData(BandDesignIntf* patternBand); + void startNewPage(); + void savePage(); + QString toString(); + +private: + DataSourceManager* m_datasources; + + PageItemDesignIntf* m_renderPageItem; + PageItemDesignIntf* m_patternPageItem; + QList m_renderedPages; + + QMultiMap< BandDesignIntf*, GroupBandsHolder* > m_childBands; + + int m_currentMaxHeight; + int m_currentStartDataPos; + int m_currentIndex; + int m_pageCount; + + QMap m_popupedValues; + QMultiMap m_popupedExpression; + + qreal m_pageFooterHeight; + qreal m_dataAreaSize; + qreal m_reportFooterHeight; + int m_renderedDataBandCount; + BandDesignIntf* m_lastDataBand; + bool m_renderCanceled; + +}; +} // namespace LimeReport +#endif // LRREPORTRENDER_H diff --git a/src/lrscriptenginemanager.cpp b/src/lrscriptenginemanager.cpp new file mode 100644 index 0000000..6c6723e --- /dev/null +++ b/src/lrscriptenginemanager.cpp @@ -0,0 +1,459 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrscriptenginemanager.h" + +#include +#include +#include +#include "lrdatasourcemanager.h" + +Q_DECLARE_METATYPE(QColor) +Q_DECLARE_METATYPE(QFont) + +QScriptValue constructColor(QScriptContext *context, QScriptEngine *engine) +{ + QColor color(context->argument(0).toString()); + return engine->toScriptValue(color); +} + +namespace LimeReport{ + +ScriptEngineNode::~ScriptEngineNode() +{ + for (int i = 0; im_childs.indexOf(const_cast(this)); + } + return 0; +} + +void ScriptEngineNode::clear() +{ + for (int i=0; iparent(); + if ((parentNode == m_rootNode) || (!parentNode)) return QModelIndex(); + return createIndex(parentNode->row(),0,parentNode); +} + +QModelIndex ScriptEngineModel::index(int row, int column, const QModelIndex& parent) const +{ + if (!m_rootNode) + return QModelIndex(); + + if (!hasIndex(row,column,parent)) + return QModelIndex(); + + ScriptEngineNode* parentNode; + if (parent.isValid()){ + parentNode = nodeFromIndex(parent); + } else { + parentNode = m_rootNode; + } + + ScriptEngineNode* childNode = parentNode->child(row); + if (childNode){ + return createIndex(row,column,childNode); + } else return QModelIndex(); +} + +int ScriptEngineModel::rowCount(const QModelIndex& parent) const +{ + if (!m_rootNode) return 0; + ScriptEngineNode* parentNode; + if (parent.isValid()) + parentNode = nodeFromIndex(parent); + else + parentNode = m_rootNode; + return parentNode->childCount(); +} + +int ScriptEngineModel::columnCount(const QModelIndex& parent) const +{ + Q_UNUSED(parent) + return 1; +} + +QVariant ScriptEngineModel::data(const QModelIndex& index, int role) const +{ + ScriptEngineNode *node = nodeFromIndex(index); + switch (role) { + case Qt::DisplayRole: + if (!node) return QVariant(); + return node->name(); + break; + case Qt::DecorationRole : + if (!node) return QIcon(); + return node->icon(); + break; + default: + return QVariant(); + } +} + +void ScriptEngineModel::setScriptEngineManager(ScriptEngineManager* scriptManager) +{ + m_scriptManager = scriptManager; + updateModel(); +} + +void ScriptEngineModel::slotScriptEngineChanged() +{ + updateModel(); +} + +ScriptEngineNode*ScriptEngineModel::nodeFromIndex(const QModelIndex& index) const +{ + if (index.isValid()){ + return static_cast(index.internalPointer()); + } else return m_rootNode; +} + +void ScriptEngineModel::updateModel() +{ + beginResetModel(); + m_rootNode->clear(); + QMap categories; + foreach(ScriptFunctionDesc funcDesc, m_scriptManager->functionsDescriber()){ + ScriptEngineNode* categ; + QString categoryName = (!funcDesc.category.isEmpty())?funcDesc.category:"NO CATEGORY"; + if (categories.contains(categoryName)){ + categ = categories.value(categoryName); + } else { + categ = m_rootNode->addChild(categoryName,ScriptEngineNode::Category,QIcon(":/report/images/folder")); + categories.insert(categoryName,categ); + } + categ->addChild(funcDesc.name,ScriptEngineNode::Function,QIcon(":/report/images/function")); + } + //reset(); + endResetModel(); +} + +QScriptValue dateToStr(QScriptContext* pcontext, QScriptEngine* pengine){ + DataSourceManager* dm = DataSourceManager::instance(); + QString field = pcontext->argument(0).toString(); + QString format = pcontext->argument(1).toString(); + QScriptValue res; + if (dm->containsField(field)){ + res=pengine->newVariant(QLocale().toString(dm->fieldData(field).toDate(),format)); + } else { + QString error = (!dm->lastError().isNull())?dm->lastError():QString("Field %1 not found").arg(field); + res=pengine->newVariant(error); + } + return res; +} + +QScriptValue line(QScriptContext* pcontext, QScriptEngine* pengine){ + DataSourceManager* dm=DataSourceManager::instance(); + QString band = pcontext->argument(0).toString(); + QScriptValue res; + QString varName = QLatin1String("line_")+band.toLower(); + if (dm->variable(varName).isValid()){ + res=pengine->newVariant(dm->variable(varName)); + } else res=pengine->newVariant(QString("Variable line for band %1 not found").arg(band)); + return res; +} + +QScriptValue numberFormat(QScriptContext* pcontext, QScriptEngine* pengine){ + QVariant value = pcontext->argument(0).toVariant(); + char format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString()[0].toLatin1():'f'; + int precision = (pcontext->argumentCount()>2)?pcontext->argument(2).toInt32():2; + QScriptValue res = pengine->newVariant(QString::number(value.toDouble(),format,precision)); + return res; +} + +QScriptValue dateFormat(QScriptContext* pcontext, QScriptEngine* pengine){ + QVariant value = pcontext->argument(0).toVariant(); + QString format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString().toLatin1():"dd.MM.yyyy"; + QScriptValue res = pengine->newVariant(QLocale().toString(value.toDate(),format)); + return res; +} + +QScriptValue now(QScriptContext* /*pcontext*/, QScriptEngine* pengine){ + return pengine->newVariant(QDate::currentDate()); +} + +QScriptValue callGroupFunction(const QString& functionName, QScriptContext* pcontext, QScriptEngine* pengine){ + + DataSourceManager* dm=DataSourceManager::instance(); + QString expression = pcontext->argument(0).toString(); + QString band = pcontext->argument(1).toString(); + QScriptValue res; + GroupFunction* gf = dm->groupFunction(functionName,expression,band); + if (gf){ + if (gf->isValid()){ + res=pengine->newVariant(gf->calculate()); + }else{ + res=pengine->newVariant(gf->error()); + } + } + else { + res=pengine->newVariant(QString(QObject::tr("Function %1 not found or have wrong arguments").arg(functionName))); + } + return res; +} + +QScriptValue groupFunction(QScriptContext* pcontext, QScriptEngine* pengine){ + return callGroupFunction(pcontext->callee().property("functionName").toString(),pcontext,pengine); +} + +ScriptEngineManager::~ScriptEngineManager() +{ + if (m_model){ + delete m_model; + m_model=0; + } + delete m_scriptEngine; +} + +QScriptValue ScriptEngineManager::addFunction(const QString& name, + QScriptEngine::FunctionSignature function, + const QString& category, + const QString& description) +{ + ScriptFunctionDesc funct; + funct.name = name; + funct.description = description; + funct.category = category; + funct.scriptValue = scriptEngine()->newFunction(function); + funct.scriptValue.setProperty("functionName",name); + funct.type = ScriptFunctionDesc::Native; + m_functions.append(funct); + if (m_model) + m_model->updateModel(); + return funct.scriptValue; +} + +QScriptValue ScriptEngineManager::addFunction(const QString& name,const QString& script, const QString& category, const QString& description) +{ + QScriptSyntaxCheckResult cr = m_scriptEngine->checkSyntax(script); + if (cr.state() == QScriptSyntaxCheckResult::Valid){ + ScriptFunctionDesc funct; + funct.scriptValue = m_scriptEngine->evaluate(script); + funct.name = name; + funct.category = category; + funct.description = description; + funct.type = ScriptFunctionDesc::Script; + m_functions.append(funct); + m_model->updateModel(); + return funct.scriptValue; + } else { + m_lastError = cr.errorMessage(); + return QScriptValue(); + } +} + +QStringList ScriptEngineManager::functionsNames() +{ + QStringList res; + foreach(ScriptFunctionDesc func, m_functions){ + res<newFunction(constructColor); + m_scriptEngine->globalObject().setProperty("QColor", colorCtor); + + QScriptValue fontProto(m_scriptEngine->newQObject(new QFontPrototype,QScriptEngine::ScriptOwnership)); + m_scriptEngine->setDefaultPrototype(qMetaTypeId(), fontProto); + QScriptValue fontConstructor = m_scriptEngine->newFunction(QFontPrototype::constructorQFont, fontProto); + m_scriptEngine->globalObject().setProperty("QFont", fontConstructor); + + DataSourceManager* dm=DataSourceManager::instance(); + foreach(QString func, dm->groupFunctionNames()){ + addFunction(func,groupFunction,"GROUP FUNCTIONS"); + } + + foreach(ScriptFunctionDesc func, m_functions){ + if (func.type==ScriptFunctionDesc::Native) + m_scriptEngine->globalObject().setProperty(func.name,func.scriptValue); + } + + m_model = new ScriptEngineModel(this); + +} + +bool ScriptExtractor::parse() +{ + int currentPos = 0; + parse(currentPos,None); + return m_scriptsBody.count()>0; + +} + +bool ScriptExtractor::parse(int &curPos,const State& state) +{ + while (curPos. * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRSCRIPTENGINEMANAGER_H +#define LRSCRIPTENGINEMANAGER_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "base/lrsingleton.h" +#include "lrscriptenginemanagerintf.h" + +namespace LimeReport{ + +struct ScriptFunctionDesc{ + enum FuncType {Native,Script}; + QScriptValue scriptValue; + QString name; + QString description; + QString category; + FuncType type; +}; + +class ScriptEngineNode { +public: + enum NodeType{Root,Category,Function}; + ScriptEngineNode(const QString& name="", NodeType type=Root, ScriptEngineNode* parent=0, const QIcon& icon=QIcon()) + :m_name(name), m_icon(icon), m_type(type), m_parent(parent){} + virtual ~ScriptEngineNode(); + int childCount(){return m_childs.count();} + ScriptEngineNode* child(int index){return m_childs[index];} + ScriptEngineNode* parent(){return m_parent;} + ScriptEngineNode* addChild(const QString& name="", NodeType type=Root, const QIcon& icon=QIcon()); + int row(); + QString name(){return m_name;} + QIcon icon(){return m_icon;} + void clear(); + NodeType type(){return m_type;} +private: + QString m_name; + QIcon m_icon; + NodeType m_type; + ScriptEngineNode* m_parent; + QVector m_childs; +}; + +class ScriptEngineManager; + +class ScriptEngineModel : public QAbstractItemModel{ + Q_OBJECT +public: + friend class ScriptEngineManager; + explicit ScriptEngineModel():m_rootNode(new ScriptEngineNode()){} + ~ScriptEngineModel(); + explicit ScriptEngineModel(ScriptEngineManager* scriptManager); + QModelIndex parent(const QModelIndex &child) const; + QModelIndex index(int row, int column, const QModelIndex &parent) const; + int rowCount(const QModelIndex &parent) const; + int columnCount(const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role) const; + void setScriptEngineManager(ScriptEngineManager* scriptManager); +private slots: + void slotScriptEngineChanged(); +private: + ScriptEngineNode* nodeFromIndex(const QModelIndex &index) const; + void updateModel(); +private: + ScriptEngineManager* m_scriptManager; + ScriptEngineNode* m_rootNode; +}; + +class ScriptEngineManager : public QObject, public Singleton, public IScriptEngineManager +{ + Q_OBJECT +public: + QScriptEngine* scriptEngine(){return m_scriptEngine;} + ~ScriptEngineManager(); + friend class Singleton; + QScriptValue addFunction(const QString& name, QScriptEngine::FunctionSignature function, + const QString& category="", const QString& description=""); + QScriptValue addFunction(const QString &name, const QString& script, + const QString &category="", const QString &description=""); + const QString& lastError() const {return m_lastError;} + QStringList functionsNames(); + const QList& functionsDescriber(){return m_functions;} + ScriptEngineModel* model(){return m_model;} +private: + Q_DISABLE_COPY(ScriptEngineManager) +private: + ScriptEngineManager(); + QScriptEngine* m_scriptEngine; + QString m_lastError; + QList m_functions; + ScriptEngineModel* m_model; +}; + +class ScriptExtractor +{ +public: + enum State{None,BuksFound,SFound,StartScriptFound,OpenBracketFound,CloseBracketFound,DFound,VFound, SignFound}; + explicit ScriptExtractor(const QString& value):m_context(value){} + bool parse(); + int count(){return m_scriptsBody.count();} + QString bodyAt(int index){return m_scriptsBody[index];} + QString scriptAt(int index){return m_scriptsStartLex[index]+m_scriptsBody[index]+'}';} + +private: + static const char SCRIPT_SIGN = 'S'; + static const char FIELD_SIGN = 'D'; + static const char VARIABLE_SIGN = 'V'; + + bool isStartLexem(int &curPos, QChar value); + bool parse(int& curPos, const State &state); + void skipField(int &curPos); + void extractScript(int& curPos, const QString &startStr); + bool extractBracket(int& curPos); + bool isStartScriptLexem(int &curPos); + bool isStartFieldLexem(int &curPos); + bool isStartVariableLexem(int &curPos); + QString substring(const QString& value, int start, int end); +private: + QString m_context; + QVector m_scriptsBody; + QVector m_scriptsStartLex; + +}; + +class QFontPrototype : public QObject, public QScriptable { + Q_OBJECT + Q_PROPERTY(QString family READ family) + Q_PROPERTY(int size READ size) + Q_PROPERTY(bool bold READ bold) + Q_PROPERTY(bool italic READ italic) + Q_PROPERTY(bool underline READ underline) +public: + QFontPrototype(QObject * parent = NULL) : QObject(parent) , QScriptable() { + this->setObjectName("QFontPrototype"); + } + QString family() const { + QFont font(qScriptValueToValue(this->thisObject())); + return font.family(); + } + int size(){ + QFont font = qScriptValueToValue(thisObject()); + return font.pointSize(); + } + bool bold(){ + QFont font = qScriptValueToValue(thisObject()); + return font.bold(); + } + bool italic(){ + QFont font = qScriptValueToValue(thisObject()); + return font.italic(); + } + bool underline(){ + QFont font = qScriptValueToValue(thisObject()); + return font.underline(); + } + static QScriptValue constructorQFont(QScriptContext * context, QScriptEngine * engine) { + QFont font; + switch (context->argumentCount()) { + case 5: font.setUnderline(qScriptValueToValue(context->argument(4))); + case 4: font.setBold(qScriptValueToValue(context->argument(3))); + case 3: font.setItalic(qScriptValueToValue(context->argument(2))); + case 2: font.setPointSize(qScriptValueToValue(context->argument(1))); + case 1: font.setFamily(qScriptValueToValue(context->argument(0))); + case 0: break; + default: + break; + } + return qScriptValueFromValue(engine, font); + } +}; + +} +#endif // LRSCRIPTENGINEMANAGER_H diff --git a/src/lrscriptenginemanagerintf.h b/src/lrscriptenginemanagerintf.h new file mode 100644 index 0000000..56284da --- /dev/null +++ b/src/lrscriptenginemanagerintf.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRSCRIPTENGINEMANAGERINTF_H +#define LRSCRIPTENGINEMANAGERINTF_H + +#include + +namespace LimeReport{ + +class IScriptEngineManager{ +public: + virtual QScriptEngine* scriptEngine() = 0; + virtual QScriptValue addFunction(const QString& name, QScriptEngine::FunctionSignature function, + const QString& category="", const QString& description="") = 0; + virtual QScriptValue addFunction(const QString &name, const QString& script, + const QString &category="", const QString &description="") = 0; + virtual const QString& lastError() const = 0; + virtual ~IScriptEngineManager(){} +}; + +} //namespace LimeReport +#endif // LRSCRIPTENGINEMANAGERINTF_H diff --git a/src/lrserializatorsfactory.cpp b/src/lrserializatorsfactory.cpp new file mode 100644 index 0000000..b1757f5 --- /dev/null +++ b/src/lrserializatorsfactory.cpp @@ -0,0 +1,30 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ + diff --git a/src/lrserializatorsfactory.h b/src/lrserializatorsfactory.h new file mode 100644 index 0000000..111484d --- /dev/null +++ b/src/lrserializatorsfactory.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef ASERIALIZATORSFACTORY_H +#define ASERIALIZATORSFACTORY_H +#include "asimpleabstractfactory.h" +#include "serializators/aserializatorintf.h" + +namespace LimeReport{ + +typedef SerializatorIntf* (*CreateSerializator)(QObject* parent); + +class SerializatorsFactory: public SimpleAbstractFactory +{ +private: + friend class Singleton; +public: + SerializatorsFactory(); + ~SerializatorsFactory(){} + SerializatorsFactory(const SerializatorsFactory&){} + SerializatorsFactory& operator = (const SerializatorsFactory&){return *this;} +}; + +} +#endif // ASERIALIZATORSFACTORY_H diff --git a/src/lrsimplecrypt.cpp b/src/lrsimplecrypt.cpp new file mode 100644 index 0000000..0b9aa06 --- /dev/null +++ b/src/lrsimplecrypt.cpp @@ -0,0 +1,183 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrsimplecrypt.h" + +#if defined(LP64) || defined(_LP64) || defined(__LP64__) +typedef unsigned int WORD; /* Should be 32-bit = 4 bytes */ +#else +typedef unsigned long int WORD; /* Should be 32-bit = 4 bytes */ +#endif + +const int w = 32; /* word size in bits */ +const int r = 12; /* number of rounds */ +const int b = 16; /* number of bytes in key */ +const int c = 4; /* number words in key = ceil(8*b/w)*/ +const int t = 26; /* size of table S = 2*(r+1) words */ + +WORD P = 0xb7e15163, Q = 0x9e3779b9; + +#define ROTL(x,y) (((x)<<(y&(w-1))) | ((x)>>(w-(y&(w-1))))) +#define ROTR(x,y) (((x)>>(y&(w-1))) | ((x)<<(w-(y&(w-1))))) + +union WTB{ + WORD word[2]; + char bytes[8]; +}; + +void initPt(WTB& pt, QByteArray::Iterator* it, QByteArray::Iterator end){ + for (int i = 0; i<8; i++){ + if (*it != end){ + pt.bytes[i]=**it; + ++*it; + } else break; + } +} + +namespace LimeReport { + +class ChipperPrivate{ + friend class Chipper; +private: + void RC5_SETUP(const char *K); + void RC5_ENCRYPT(WORD *pt, WORD *ct); + void RC5_DECRYPT(WORD *ct, WORD *pt); + WORD S[26]; +}; + +void ChipperPrivate::RC5_SETUP(const char *K) +{ + WORD i, j, k, u=w/8, A, B, L[c]; + for (i=b,L[c-1]=0; i!=0; i--) + L[(i-1)/u] = (L[(i-1)/u]<<8)+K[i-1]; + for (S[0]=P,i=1; i 3*c */ + A = S[i] = ROTL(S[i]+(A+B),3); + B = L[j] = ROTL(L[j]+(A+B),(A+B)); + } +} + +void ChipperPrivate::RC5_ENCRYPT(WORD *pt, WORD *ct) +{ + WORD i, A=pt[0]+S[0], B=pt[1]+S[1]; + for (i=1; i<=r; i++) + { A = ROTL(A^B,B)+S[2*i]; + B = ROTL(B^A,A)+S[2*i+1]; + } + ct[0] = A; ct[1] = B; +} + +void ChipperPrivate::RC5_DECRYPT(WORD *ct, WORD *pt) +{ + WORD i, B=ct[1], A=ct[0]; + for (i=r; i>0; i--) + { B = ROTR(B-S[2*i+1],A)^A; + A = ROTR(A-S[2*i],B)^B; + } + pt[1] = B-S[1]; pt[0] = A-S[0]; +} + +QByteArray Chipper::cryptString(QString value) +{ + QByteArray buff; + QByteArray result; + buff += value; + WTB pt, ct, prior; + + d->RC5_SETUP("HjccbzHjlbyfCkjy"); + + prior.word[0]=0; + prior.word[1]=0; + + QByteArray::Iterator it = buff.begin(); + while (it!=buff.end()){ + + pt.word[0] = 0; + pt.word[1] = 0; + + initPt(pt,&it,buff.end()); + + pt.word[0] = pt.word[0] ^ prior.word[0]; + pt.word[1] = pt.word[1] ^ prior.word[1]; + + d->RC5_ENCRYPT(pt.word,ct.word); + + prior.word[0] = pt.word[0]; + prior.word[1] = pt.word[1]; + + for (int i=0;i<8;i++){ + result += ct.bytes[i]; + } + } + return result; +} + +QString Chipper::decryptByteArray(QByteArray value) +{ + QByteArray result; + WTB pt, ct, prior; + + d->RC5_SETUP("HjccbzHjlbyfCkjy"); + prior.word[0] = 0; + prior.word[1] = 0; + + QByteArray::Iterator it = value.begin(); + while (it!=value.end()){ + + pt.word[0] = 0; + pt.word[1] = 0; + + initPt(pt,&it,value.end()); + + d->RC5_DECRYPT(pt.word,ct.word); + + ct.word[0] = ct.word[0] ^ prior.word[0]; + ct.word[1] = ct.word[1] ^ prior.word[1]; + + prior.word[0] = ct.word[0]; + prior.word[1] = ct.word[1]; + + for (int i=0;i<8;i++){ + result += ct.bytes[i]; + } + + } + return QString(result); +} + +Chipper::Chipper(): d(new ChipperPrivate()){} + +Chipper::~Chipper() +{ + delete d; +} + +} + diff --git a/src/lrsimplecrypt.h b/src/lrsimplecrypt.h new file mode 100644 index 0000000..68978b5 --- /dev/null +++ b/src/lrsimplecrypt.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRSIMPLECRYPT_H +#define LRSIMPLECRYPT_H + +#include +#include +#include + +namespace LimeReport { + +class ChipperPrivate; +class Chipper{ +public: + QByteArray cryptString(QString value); + QString decryptByteArray(QByteArray value); + Chipper(); + ~Chipper(); +private: + ChipperPrivate* d; +}; + +} + +#endif // LRSIMPLECRYPT_H diff --git a/src/lrvariablesholder.cpp b/src/lrvariablesholder.cpp new file mode 100644 index 0000000..7b3d224 --- /dev/null +++ b/src/lrvariablesholder.cpp @@ -0,0 +1,147 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrvariablesholder.h" +#include +#include +#include + +namespace LimeReport{ + +AVariablesHolder::AVariablesHolder(QObject *parent) : + QObject(parent) +{ +} + +AVariablesHolder::~AVariablesHolder() +{ + QMap::iterator it = m_varNames.begin(); + while(it!=m_varNames.end()){ + delete *it; + it++; + } + m_varNames.clear(); + m_userVariables.clear(); +} + +void AVariablesHolder::addVariable(const QString& name, const QVariant& value, VarDesc::VarType type, RenderPass pass) +{ + if (!m_varNames.contains(name)){ + VarDesc* varValue = new VarDesc; + varValue->setName(name); + varValue->setValue(value); + varValue->setVarType(type); + varValue->setRenderPass(pass); + m_varNames.insert(name,varValue); + if (type==VarDesc::User) + m_userVariables.append(varValue); + } else { + throw ReportError(tr("variable with name ")+name+tr(" already exists !!")); + } +} + +QVariant AVariablesHolder::variable(const QString &name) +{ + if (m_varNames.contains(name)) + return m_varNames.value(name)->value(); + else return QVariant(); +} + +VarDesc::VarType AVariablesHolder::variableType(const QString &name) +{ + if (m_varNames.contains(name)) + return m_varNames.value(name)->varType(); + else throw ReportError(tr("variable with name ")+name+tr(" does not exists !!")); +} + +void AVariablesHolder::deleteVariable(const QString &name) +{ + if (m_varNames.contains(name)) { + m_userVariables.removeOne(m_varNames.value(name)); + delete m_varNames.value(name); + m_varNames.remove(name); + } +} + +void AVariablesHolder::changeVariable(const QString &name, const QVariant &value) +{ + if(m_varNames.contains(name)) { + m_varNames.value(name)->setValue(value); + } else + throw ReportError(tr("variable with name ")+name+tr(" does not exists !!")); +} + +void AVariablesHolder::clearUserVariables() +{ + QMap::iterator it = m_varNames.begin(); + while (it != m_varNames.end()){ + if (it.value()->varType()==VarDesc::User){ + m_userVariables.removeAll(it.value()); + delete it.value(); + it = m_varNames.erase(it); + } else { + ++it; + } + + } + +} + +bool AVariablesHolder::containsVariable(const QString &name) +{ + return m_varNames.contains(name); +} + +int AVariablesHolder::userVariablesCount() +{ + return m_userVariables.count(); +} + +VarDesc *AVariablesHolder::userVariableAt(int index) +{ + return m_userVariables.at(index); +} + +QStringList AVariablesHolder::variableNames() +{ + QStringList result; + foreach(QString varName,m_varNames.keys()){ + result<renderPass(); + else throw ReportError(tr("variable with name ")+name+tr(" does not exists !!")); +} + +}// namespace LimeReport diff --git a/src/lrvariablesholder.h b/src/lrvariablesholder.h new file mode 100644 index 0000000..c55397f --- /dev/null +++ b/src/lrvariablesholder.h @@ -0,0 +1,102 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef VARIABLEHOLDER_H +#define VARIABLEHOLDER_H + +#include +#include +#include +#include +#include "lrglobal.h" + +namespace LimeReport{ + +class VarDesc : public QObject{ + Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(QVariant value READ value WRITE setValue) +public: + enum VarType {System,User}; + void setVarType(VarType value){m_varType=value;} + VarType varType(){return m_varType;} + void setRenderPass(RenderPass value){m_varPass=value;} + RenderPass renderPass(){return m_varPass;} + void setName(QString value){m_name=value;} + QString name(){return m_name;} + void setValue(QVariant value){m_value=value;} + QVariant value(){return m_value;} +private: + VarType m_varType; + RenderPass m_varPass; + QString m_name; + QVariant m_value; +}; + +class IVariablesContainer +{ +public: + virtual ~IVariablesContainer(){} + virtual void addVariable(const QString &name, const QVariant &value, VarDesc::VarType type=VarDesc::User, RenderPass pass=FirstPass)=0; + virtual void deleteVariable(const QString &name)=0; + virtual void changeVariable(const QString &name, const QVariant &value)=0; + virtual void clearUserVariables()=0; + virtual QVariant variable(const QString &name)=0; + virtual VarDesc::VarType variableType(const QString &name)=0; + virtual RenderPass variablePass(const QString &name)=0; + virtual bool containsVariable(const QString &name)=0; + virtual QStringList variableNames()=0; +}; + +class AVariablesHolder : public QObject, public IVariablesContainer +{ + Q_OBJECT +public: + explicit AVariablesHolder(QObject *parent = 0); + ~AVariablesHolder(); + void addVariable(const QString &name, const QVariant &value, VarDesc::VarType type=VarDesc::User, RenderPass pass=FirstPass); + void deleteVariable(const QString &name); + void changeVariable(const QString &name, const QVariant &value); + void clearUserVariables(); + QVariant variable(const QString &name); + VarDesc::VarType variableType(const QString &name); + RenderPass variablePass(const QString &name); + bool containsVariable(const QString &name); + QStringList variableNames(); + int userVariablesCount(); + VarDesc* userVariableAt(int index); +signals: +private: + QMap m_varNames; + QList m_userVariables; +}; + +}// namespace LimeReport + +#endif // VARIABLEHOLDER_H diff --git a/src/objectinspector/editors/lrbuttonlineeditor.cpp b/src/objectinspector/editors/lrbuttonlineeditor.cpp new file mode 100644 index 0000000..33095db --- /dev/null +++ b/src/objectinspector/editors/lrbuttonlineeditor.cpp @@ -0,0 +1,140 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrbuttonlineeditor.h" +#include +#include +#include +#include +#include +#include +#include +#include "lrtextitempropertyeditor.h" + +ButtonLineEditor::ButtonLineEditor(const QString &propertyName, QWidget *parent) : + QWidget(parent), m_overButton(false), m_editor(0), m_propertyName(propertyName) +{ + m_lineEdit = new QLineEdit(this); + m_lineEdit->installEventFilter(this); + setFocusProxy(m_lineEdit); + m_buttonEdit = new QToolButton(this); + m_buttonEdit->setText("..."); + m_buttonEdit->installEventFilter(this); + m_buttonEdit->setAttribute(Qt::WA_Hover); + + QHBoxLayout *layout = new QHBoxLayout(this); + layout->addWidget(m_lineEdit); + layout->addWidget(m_buttonEdit); + layout->setContentsMargins(1,1,1,1); + layout->setSpacing(0); + setAutoFillBackground(true); + connect(m_buttonEdit,SIGNAL(clicked()),this,SLOT(editButtonClicked())); + //connect(m_lineEdit,SIGNAL(editingFinished()),this,SLOT(lineEditEditingFinished())); +} + +ButtonLineEditor::~ButtonLineEditor() +{ + if (m_editor) { + delete m_editor; + m_editor = 0; + } +} + +void ButtonLineEditor::editButtonClicked() +{ + + if (!m_editor){ + m_editor = new TextItemPropertyEditor(QApplication::activeWindow()); + m_editor->setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, m_editor->size(), QApplication::desktop()->availableGeometry())); + m_editor->setWindowTitle(m_propertyName); + m_editor->setText(m_lineEdit->text()); + connect(m_editor,SIGNAL(accepted()),this,SLOT(editingByEditorFinished())); + m_editor->exec(); + } else m_editor->exec(); +} + +void ButtonLineEditor::setText(const QString &value){ + m_lineEdit->setText(value); +} + +QString ButtonLineEditor::text() +{ + return m_lineEdit->text(); +} + +bool ButtonLineEditor::eventFilter(QObject *target, QEvent *event) +{ + + if (target==m_buttonEdit) { + + if (event->type()==QEvent::HoverEnter){ + m_overButton=true; + } + if (event->type()==QEvent::HoverLeave){ + m_overButton=false; + } + if (event->type()==QEvent::FocusOut){ + if (static_cast(event)->reason()!=Qt::MouseFocusReason){ + m_lineEdit->setFocus(); + } + } + QSet enterKeys; + enterKeys.insert(Qt::Key_Enter); + enterKeys.insert(Qt::Key_Return); + + if (event->type()==QEvent::KeyPress){ + if (enterKeys.contains(static_cast(event)->key())){ + m_buttonEdit->click(); + return true; + } + } + } + if (target==m_lineEdit){ + if (event->type()==QEvent::FocusOut){ + switch (static_cast(event)->reason()){ + case Qt::TabFocusReason: + m_overButton=true; + break; + case Qt::MouseFocusReason: + break; + default: + m_overButton=false; + } + + } + } + return QWidget::eventFilter(target,event); + +} + +void ButtonLineEditor::editingByEditorFinished() +{ + setText(qobject_cast(sender())->text()); + m_lineEdit->setFocus(); +} diff --git a/src/objectinspector/editors/lrbuttonlineeditor.h b/src/objectinspector/editors/lrbuttonlineeditor.h new file mode 100644 index 0000000..6e41b1f --- /dev/null +++ b/src/objectinspector/editors/lrbuttonlineeditor.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRBUTTONLINEEDIT_H +#define LRBUTTONLINEEDIT_H + +#include +#include +#include +#include +#include +#include +#include "lrtextitempropertyeditor.h" + + +class ButtonLineEditor : public QWidget +{ + Q_OBJECT +public: + explicit ButtonLineEditor(const QString& propertyName,QWidget *parent = 0); + ~ButtonLineEditor(); + void setText(const QString &value); + QString text(); +signals: + void editingFinished(); +public slots: + void editButtonClicked(); + void editingByEditorFinished(); +private: + QLineEdit* m_lineEdit; + QToolButton* m_buttonEdit; + bool m_overButton; + TextItemPropertyEditor *m_editor; + QString m_propertyName; +private: + bool eventFilter(QObject *, QEvent *); + //QHBoxLayout* m_layout; +}; + +#endif // LRBUTTONLINEEDIT_H diff --git a/src/objectinspector/editors/lrcheckboxeditor.cpp b/src/objectinspector/editors/lrcheckboxeditor.cpp new file mode 100644 index 0000000..ec61301 --- /dev/null +++ b/src/objectinspector/editors/lrcheckboxeditor.cpp @@ -0,0 +1,115 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrcheckboxeditor.h" +#include +#include +#include +#include +#include +#include + +namespace LimeReport{ + +CheckBoxEditor::CheckBoxEditor(QWidget *parent) + :QWidget(parent), m_editing(false) +{ + m_checkBox = new QCheckBox(this); + init(); +} +CheckBoxEditor::CheckBoxEditor(const QString &text, QWidget *parent) + :QWidget(parent), m_editing(false) +{ + m_checkBox = new QCheckBox(text,this); + init(); +} + +CheckBoxEditor::~CheckBoxEditor(){} + +void CheckBoxEditor::init() +{ + QVBoxLayout *layout=new QVBoxLayout(this); + layout->addStretch(); + layout->addWidget(m_checkBox); + m_checkBox->setFocusPolicy(Qt::NoFocus); + connect(m_checkBox, SIGNAL(stateChanged(int)), this, SLOT(slotStateChanged(int))); + layout->addStretch(); + layout->setContentsMargins(2,1,1,1); + layout->setSpacing(0); + setLayout(layout); + setAutoFillBackground(true); + setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed); +} + +void CheckBoxEditor::setEditing(bool value) +{ + m_editing=value; +} + +void CheckBoxEditor::setChecked(bool value) +{ + m_checkBox->setChecked(value); +} + +bool CheckBoxEditor::isChecked() +{ + return m_checkBox->isChecked(); +} + +void CheckBoxEditor::mousePressEvent(QMouseEvent *) +{ + m_checkBox->setChecked(!m_checkBox->isChecked()); + emit editingFinished(); +} + +void CheckBoxEditor::keyPressEvent(QKeyEvent *event) +{ + if (event->key()==Qt::Key_Space) m_checkBox->setChecked(!m_checkBox->isChecked()); + if ((event->key() == Qt::Key_Up) || (event->key() == Qt::Key_Down)){ + emit editingFinished(); + } + QWidget::keyPressEvent(event); +} + +void CheckBoxEditor::showEvent(QShowEvent *) +{ + int border = (height() - QApplication::style()->pixelMetric(QStyle::PM_IndicatorWidth))/2 +#ifdef Q_OS_MAC + +QApplication::style()->pixelMetric(QStyle::PM_FocusFrameVMargin) +#endif + ; + layout()->setContentsMargins(border,0,0,0); +} + +void CheckBoxEditor::slotStateChanged(int) +{ + emit editingFinished(); +} + +} diff --git a/src/objectinspector/editors/lrcheckboxeditor.h b/src/objectinspector/editors/lrcheckboxeditor.h new file mode 100644 index 0000000..67c95bf --- /dev/null +++ b/src/objectinspector/editors/lrcheckboxeditor.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRCHECKBOXEDITOR_H +#define LRCHECKBOXEDITOR_H + +#include + +namespace LimeReport{ + +class CheckBoxEditor : public QWidget +{ + Q_OBJECT + +public: + CheckBoxEditor(QWidget * parent = 0); + CheckBoxEditor(const QString & text, QWidget * parent = 0); + ~CheckBoxEditor(); + void setEditing(bool value); + void setChecked(bool value); + bool isChecked(); +protected: + void mousePressEvent(QMouseEvent *); + void keyPressEvent(QKeyEvent *event); + void showEvent(QShowEvent *); +signals: + void editingFinished(); +private slots: + void slotStateChanged(int); +private: + QCheckBox* m_checkBox; + bool m_editing; + void init(); + +}; + +} +#endif // LRCHECKBOXEDITOR_H diff --git a/src/objectinspector/editors/lrcoloreditor.cpp b/src/objectinspector/editors/lrcoloreditor.cpp new file mode 100644 index 0000000..015dde1 --- /dev/null +++ b/src/objectinspector/editors/lrcoloreditor.cpp @@ -0,0 +1,72 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrcoloreditor.h" + +#include +#include + +ColorEditor::ColorEditor(QWidget *parent) : + QWidget(parent) +{ + //m_button = new QPushButton(this); + m_button = new QToolButton(this); + m_button->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed); + QHBoxLayout* layout = new QHBoxLayout(this); + layout->addWidget(m_button); + layout->setSpacing(0); + layout->setContentsMargins(1,1,1,1); + setFocusProxy(m_button); + setAutoFillBackground(true); + setLayout(layout); + connect(m_button,SIGNAL(clicked()),this,SLOT(slotClicked())); +} + +void ColorEditor::setColor(const QColor &value) +{ + m_color=value; +} + +void ColorEditor::showEvent(QShowEvent *) +{ + QPixmap pixmap(m_button->width()-8,m_button->height()-8); + pixmap.fill(m_color); + m_button->setIcon(QIcon(pixmap)); + m_button->setIconSize(QSize(m_button->width()-8,m_button->height()-8)); +} + +void ColorEditor::slotClicked() +{ + QColorDialog* dialog = new QColorDialog(this); + dialog->setCurrentColor(m_color); + if (dialog->exec()) m_color=dialog->currentColor(); + delete dialog; + emit(editingFinished()); +} + diff --git a/src/objectinspector/editors/lrcoloreditor.h b/src/objectinspector/editors/lrcoloreditor.h new file mode 100644 index 0000000..28856d9 --- /dev/null +++ b/src/objectinspector/editors/lrcoloreditor.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRCOLOREDITOR_H +#define LRCOLOREDITOR_H + +#include +#include +#include + +class ColorEditor : public QWidget +{ + Q_OBJECT +public: + explicit ColorEditor(QWidget *parent = 0); + QColor color(){return m_color;} + void setColor(const QColor& value); +protected: + void showEvent(QShowEvent *); +signals: + void editingFinished(); +private slots: + void slotClicked(); +private: + QColor m_color; +// QPushButton* m_button; + QToolButton* m_button; +}; + +#endif // LRCOLOREDITOR_H diff --git a/src/objectinspector/editors/lrcomboboxeditor.cpp b/src/objectinspector/editors/lrcomboboxeditor.cpp new file mode 100644 index 0000000..c0b8464 --- /dev/null +++ b/src/objectinspector/editors/lrcomboboxeditor.cpp @@ -0,0 +1,140 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include "lrcomboboxeditor.h" + +ComboBoxEditor::ComboBoxEditor(QWidget *parent, bool clearable) : + QWidget(parent), + m_comboBox(new InternalComboBox(this)), + m_buttonClear(0), + m_settingValues(false) +{ + setFocusProxy(m_comboBox); + + if (clearable) { + m_buttonClear = new QToolButton(this); + m_buttonClear->setIcon(QIcon(":/items/clear.png")); + m_buttonClear->installEventFilter(this); + m_buttonClear->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Expanding); + m_buttonClear->setMaximumHeight(QWIDGETSIZE_MAX); + connect(m_buttonClear,SIGNAL(clicked()),this,SLOT(slotClearButtonClicked())); + } + + connect(m_comboBox,SIGNAL(currentIndexChanged(QString)),this,SLOT(slotCurrentIndexChanged(QString))); + m_comboBox->installEventFilter(this); + QHBoxLayout *layout = new QHBoxLayout(this); + layout->addWidget(m_comboBox); + if (clearable) + layout->addWidget(m_buttonClear); + layout->setContentsMargins(0,0,0,0); + layout->setSpacing(2); + setLayout(layout); + setAutoFillBackground(true); +} + +void ComboBoxEditor::addItems(const QStringList &values){ + m_settingValues = true; + m_comboBox->addItems(values); + m_settingValues = false; +} + +void ComboBoxEditor::setTextValue(const QString &value){ + m_settingValues = true; + if (m_comboBox->findText(value)>0){ + m_comboBox->setCurrentIndex(m_comboBox->findText(value)); + } else { + m_comboBox->setEditText(value); + } + m_settingValues = false; +} + +void ComboBoxEditor::slotClearButtonClicked(){ + m_comboBox->setCurrentIndex(-1); +} + +void ComboBoxEditor::slotCurrentIndexChanged(const QString& value) +{ + if (!m_settingValues){ + emit currentIndexChanged(value); + } +} + +QString ComboBoxEditor::text(){ + return m_comboBox->currentText(); +} + +void ComboBoxEditor::setEditable(bool value) +{ + if (m_comboBox) { + m_comboBox->setEditable(value); + } +} + +bool ComboBoxEditor::eventFilter(QObject *target, QEvent *event){ + if (target == m_buttonClear){ + if (event->type()==QEvent::FocusOut){ + if (static_cast(event)->reason()!=Qt::MouseFocusReason){ + m_comboBox->setFocus(); + } + } + QSet enterKeys; + enterKeys.insert(Qt::Key_Enter); + enterKeys.insert(Qt::Key_Return); + + if (event->type()==QEvent::KeyPress){ + if (enterKeys.contains(static_cast(event)->key())){ + m_buttonClear->click(); + return true; + } + } + } + + if (target == m_comboBox){ + if (event->type() == QEvent::FocusOut){ + if (!m_comboBox->isPopup() || (m_buttonClear && m_buttonClear->hasFocus())) + emit editingFinished(); + } + } + return QWidget::eventFilter(target,event); +} + + +void ComboBoxEditor::resizeEvent(QResizeEvent *e) +{ + if (m_buttonClear) + m_buttonClear->setMinimumHeight(e->size().height()-4); +} diff --git a/src/objectinspector/editors/lrcomboboxeditor.h b/src/objectinspector/editors/lrcomboboxeditor.h new file mode 100644 index 0000000..ac69c24 --- /dev/null +++ b/src/objectinspector/editors/lrcomboboxeditor.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRCOMBOBOXEDITOR_H +#define LRCOMBOBOXEDITOR_H + +#include +#include +//#include + +class QToolButton; + +class InternalComboBox :public QComboBox{ + Q_OBJECT +public: + InternalComboBox(QWidget* parent=0):QComboBox(parent),m_popup(false){} + void showPopup(){m_popup = true;QComboBox::showPopup();} + void hidePopup(){QComboBox::hidePopup(); m_popup = false;} + bool isPopup(){return m_popup;} +private: + bool m_popup; + +}; + +class ComboBoxEditor : public QWidget +{ + Q_OBJECT +public: + //explicit ComboBoxEditor(QWidget *parent = 0); + ComboBoxEditor(QWidget *parent=0, bool clearable=true); + void addItems(const QStringList& values); + void setTextValue(const QString& value); + QString text(); + void setEditable(bool value); +signals: + void editingFinished(); + void currentIndexChanged(const QString&); +protected: + void resizeEvent(QResizeEvent *e); +private slots: + void slotClearButtonClicked(); + void slotCurrentIndexChanged(const QString& value); +private: + bool eventFilter(QObject *target, QEvent *event); + InternalComboBox* m_comboBox; + QToolButton* m_buttonClear; + bool m_settingValues; +}; + +#endif // LRCOMBOBOXEDITOR_H diff --git a/src/objectinspector/editors/lrfonteditor.cpp b/src/objectinspector/editors/lrfonteditor.cpp new file mode 100644 index 0000000..421be77 --- /dev/null +++ b/src/objectinspector/editors/lrfonteditor.cpp @@ -0,0 +1,81 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrfonteditor.h" +#include +#include +#include + +FontEditor::FontEditor(QWidget *parent) : + QWidget(parent) +{ + //m_button = new QPushButton(this); + m_button = new QToolButton(this); + m_button->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed); + QHBoxLayout* layout = new QHBoxLayout(this); + layout->addWidget(m_button); + layout->setSpacing(0); + layout->setContentsMargins(1,1,1,1); + setFocusProxy(m_button); + setLayout(layout); + setAutoFillBackground(true); + connect(m_button,SIGNAL(clicked()),this,SLOT(slotButtonCliked())); +} + +FontEditor::~FontEditor() +{} + +void FontEditor::setFontValue(const QFont &font) +{ + m_font=font; + m_button->setText(toString(font)); +} + +QFont FontEditor::fontValue() +{ + return m_font; +} + +void FontEditor::slotButtonCliked() +{ + QFontDialog* dialog = new QFontDialog(this); + dialog->setCurrentFont(m_font); + if (dialog->exec()) m_font=dialog->currentFont(); + delete dialog; + emit(editingFinished()); +} + +QString FontEditor::toString(const QFont &value) const +{ + QString attribs="["; + if (value.bold()) (attribs=="[") ? attribs+="b":attribs+=",b"; + if (value.italic()) (attribs=="[") ? attribs+="i":attribs+=",i"; + attribs+="]"; + return value.family()+" "+QString::number(value.pointSize())+" "+attribs; +} diff --git a/src/objectinspector/editors/lrfonteditor.h b/src/objectinspector/editors/lrfonteditor.h new file mode 100644 index 0000000..703ed91 --- /dev/null +++ b/src/objectinspector/editors/lrfonteditor.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRFONTEDITOR_H +#define LRFONTEDITOR_H + +#include +#include +#include + +class FontEditor : public QWidget +{ + Q_OBJECT +public: + explicit FontEditor(QWidget *parent = 0); + ~FontEditor(); + void setFontValue(const QFont &font); + QFont fontValue(); +signals: + void editingFinished(); +public slots: + void slotButtonCliked(); +private: + QString toString(const QFont& value) const; +private: + //QPushButton* m_button; + QToolButton* m_button; + QFont m_font; +}; + +#endif // LRFONTEDITOR_H diff --git a/src/objectinspector/editors/lrimageeditor.cpp b/src/objectinspector/editors/lrimageeditor.cpp new file mode 100644 index 0000000..42bc2e1 --- /dev/null +++ b/src/objectinspector/editors/lrimageeditor.cpp @@ -0,0 +1,56 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include +#include +#include "lrimageeditor.h" + +ImageEditor::ImageEditor(QWidget* parent) + :QWidget(parent) +{ + m_button.setIcon(QIcon(":items/ImageItem")); + QHBoxLayout* layout = new QHBoxLayout(this); + layout->addWidget(&m_button); + layout->setSpacing(0); + layout->setContentsMargins(1,0,1,1); + setLayout(layout); + setFocusProxy(&m_button); + connect(&m_button,SIGNAL(clicked()),this,SLOT(slotButtonClicked())); +} + +QImage ImageEditor::image() +{ + return m_image; +} + +void ImageEditor::slotButtonClicked() +{ + m_image.load(QFileDialog::getOpenFileName(this)); + emit editingFinished(); +} diff --git a/src/objectinspector/editors/lrimageeditor.h b/src/objectinspector/editors/lrimageeditor.h new file mode 100644 index 0000000..0cd573e --- /dev/null +++ b/src/objectinspector/editors/lrimageeditor.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRIMAGEEDITOR_H +#define LRIMAGEEDITOR_H +#include +#include + +class ImageEditor : public QWidget +{ + Q_OBJECT + +public: + ImageEditor(QWidget *parent=0); + QImage image(); + void setImage(const QImage& image){m_image=image;} +signals: + void editingFinished(); +private slots: + void slotButtonClicked(); +private: + QPushButton m_button; + QImage m_image; +}; + +#endif // LRIMAGEEDITOR_H diff --git a/src/objectinspector/editors/lrtextitempropertyeditor.cpp b/src/objectinspector/editors/lrtextitempropertyeditor.cpp new file mode 100644 index 0000000..c27c7f4 --- /dev/null +++ b/src/objectinspector/editors/lrtextitempropertyeditor.cpp @@ -0,0 +1,55 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrtextitempropertyeditor.h" +#include "ui_ltextitempropertyeditor.h" +#include + +TextItemPropertyEditor::TextItemPropertyEditor(QWidget *parent) : + QDialog(parent), + ui(new Ui::TextItemPropertyEditor) +{ + ui->setupUi(this); + ui->textEdit->setAcceptRichText(false); +} + +TextItemPropertyEditor::~TextItemPropertyEditor() +{ + delete ui; +} + +void TextItemPropertyEditor::setText(const QString &value) +{ + ui->textEdit->setPlainText(value); +} + +QString TextItemPropertyEditor::text() +{ + return ui->textEdit->toPlainText(); +} diff --git a/src/objectinspector/editors/lrtextitempropertyeditor.h b/src/objectinspector/editors/lrtextitempropertyeditor.h new file mode 100644 index 0000000..b50c536 --- /dev/null +++ b/src/objectinspector/editors/lrtextitempropertyeditor.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef ATEXTITEMPROPERTYEDITOR_H +#define ATEXTITEMPROPERTYEDITOR_H + +#include +#include + +namespace Ui { + class TextItemPropertyEditor; +} + +class TextItemPropertyEditor : public QDialog +{ + Q_OBJECT +public: + explicit TextItemPropertyEditor(QWidget *parent = 0); + ~TextItemPropertyEditor(); + void setText(const QString &value); + QString text(); +public slots: + void pbSaveCliked(){ emit editingFinished();} +signals: + void editingFinished(); +private: + Ui::TextItemPropertyEditor *ui; +}; + +#endif // ATEXTITEMPROPERTYEDITOR_H diff --git a/src/objectinspector/editors/ltextitempropertyeditor.ui b/src/objectinspector/editors/ltextitempropertyeditor.ui new file mode 100644 index 0000000..e31e8be --- /dev/null +++ b/src/objectinspector/editors/ltextitempropertyeditor.ui @@ -0,0 +1,80 @@ + + + TextItemPropertyEditor + + + Qt::WindowModal + + + + 0 + 0 + 400 + 300 + + + + + :/items/images/insert-text_3.png:/items/images/insert-text_3.png + + + true + + + true + + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + TextItemPropertyEditor + accept() + + + 54 + 277 + + + 5 + 258 + + + + + buttonBox + rejected() + TextItemPropertyEditor + reject() + + + 161 + 266 + + + 397 + 225 + + + + + + pbSaveCliked() + pbCancelCliked() + + diff --git a/src/objectinspector/images/check.png b/src/objectinspector/images/check.png new file mode 100644 index 0000000..c4e2fb3 Binary files /dev/null and b/src/objectinspector/images/check.png differ diff --git a/src/objectinspector/images/check_w.png b/src/objectinspector/images/check_w.png new file mode 100644 index 0000000..9169b6e Binary files /dev/null and b/src/objectinspector/images/check_w.png differ diff --git a/src/objectinspector/images/checked.png b/src/objectinspector/images/checked.png new file mode 100644 index 0000000..07d1faf Binary files /dev/null and b/src/objectinspector/images/checked.png differ diff --git a/src/objectinspector/images/clear.png b/src/objectinspector/images/clear.png new file mode 100644 index 0000000..bfc2b44 Binary files /dev/null and b/src/objectinspector/images/clear.png differ diff --git a/src/objectinspector/images/edit_16.ico b/src/objectinspector/images/edit_16.ico new file mode 100644 index 0000000..b44d917 Binary files /dev/null and b/src/objectinspector/images/edit_16.ico differ diff --git a/src/objectinspector/images/uncheck.png b/src/objectinspector/images/uncheck.png new file mode 100644 index 0000000..c374c59 Binary files /dev/null and b/src/objectinspector/images/uncheck.png differ diff --git a/src/objectinspector/images/uncheck_w.png b/src/objectinspector/images/uncheck_w.png new file mode 100644 index 0000000..838c0ab Binary files /dev/null and b/src/objectinspector/images/uncheck_w.png differ diff --git a/src/objectinspector/images/unchecked.png b/src/objectinspector/images/unchecked.png new file mode 100644 index 0000000..574c0d4 Binary files /dev/null and b/src/objectinspector/images/unchecked.png differ diff --git a/src/objectinspector/lobjectinspector.qrc b/src/objectinspector/lobjectinspector.qrc new file mode 100644 index 0000000..7dd5e48 --- /dev/null +++ b/src/objectinspector/lobjectinspector.qrc @@ -0,0 +1,10 @@ + + + images/clear.png + images/edit_16.ico + images/check.png + images/uncheck.png + images/check_w.png + images/uncheck_w.png + + diff --git a/src/objectinspector/lrbasedesignobjectmodel.cpp b/src/objectinspector/lrbasedesignobjectmodel.cpp new file mode 100644 index 0000000..8f22a97 --- /dev/null +++ b/src/objectinspector/lrbasedesignobjectmodel.cpp @@ -0,0 +1,51 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrbasedesignobjectmodel.h" +#include "lrbasedesignintf.h" + +namespace LimeReport{ + +BaseDesignPropertyModel::BaseDesignPropertyModel(QObject *parent) + : QObjectPropertyModel(parent) +{} + +void BaseDesignPropertyModel::setObject(QObject *object) +{ + BaseDesignIntf* reportItem = dynamic_cast(object); + if (reportItem){ + connect(reportItem,SIGNAL(propertyChanged(QString,QVariant,QVariant)),this,SLOT(slotPropertyChanged(QString,QVariant,QVariant))); + + } + QObjectPropertyModel::setObject(object); +} + +} + + diff --git a/src/objectinspector/lrbasedesignobjectmodel.h b/src/objectinspector/lrbasedesignobjectmodel.h new file mode 100644 index 0000000..518d3a8 --- /dev/null +++ b/src/objectinspector/lrbasedesignobjectmodel.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRBASEDESIGNOBJECTSMODEL_H +#define LRBASEDESIGNOBJECTSMODEL_H + +#include "lrobjectitemmodel.h" +#include +namespace LimeReport{ +class BaseDesignPropertyModel : public QObjectPropertyModel +{ +public: + explicit BaseDesignPropertyModel(QObject* parent=0); + virtual void setObject(QObject *object); +}; +} +#endif // LRBASEDESIGNOBJECTSMODEL_H diff --git a/src/objectinspector/lrobjectinspectorwidget.cpp b/src/objectinspector/lrobjectinspectorwidget.cpp new file mode 100644 index 0000000..4405f7d --- /dev/null +++ b/src/objectinspector/lrobjectinspectorwidget.cpp @@ -0,0 +1,158 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include +#include +#include + +#include "lrglobal.h" +#include "lrobjectinspectorwidget.h" +#include "lrobjectitemmodel.h" + +namespace LimeReport{ + +ObjectInspectorWidget::ObjectInspectorWidget(QWidget *parent) + :QTreeView(parent), m_propertyDelegate(0) +{ + setRootIsDecorated(false); + initColorMap(); + setEditTriggers( + QAbstractItemView::DoubleClicked | + QAbstractItemView::SelectedClicked | + QAbstractItemView::EditKeyPressed + ); + m_propertyDelegate = new PropertyDelegate(this); + setItemDelegate(m_propertyDelegate); + QPalette p = palette(); + p.setColor(QPalette::AlternateBase,QColor(229,255,214)); + setPalette(p); +} + +ObjectInspectorWidget::~ObjectInspectorWidget(){} + +void ObjectInspectorWidget::drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const +{ + ObjectPropItem *node = nodeFromIndex(index); + QStyleOptionViewItemV4 so = options; + bool alternate = so.features & QStyleOptionViewItemV4::Alternate; + if (node){ + if ((!node->isHaveValue())){ + const QColor c = options.palette.color(QPalette::Dark); + painter->fillRect(options.rect,c); + so.palette.setColor(QPalette::AlternateBase,c); + } else { + if ( index.isValid()&&(nodeFromIndex(index)->colorIndex()!=-1) ){ + QColor fillColor(getColor(nodeFromIndex(index)->colorIndex()%m_colors.count())); + so.palette.setColor(QPalette::AlternateBase,fillColor.lighter(115)); + if (!alternate){ + painter->fillRect(options.rect,fillColor); + } + } + } + } + QTreeView::drawRow(painter,so,index); + painter->save(); + QColor gridLineColor = static_cast(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor,&so)); + painter->setPen(gridLineColor); + painter->drawLine(so.rect.x(),so.rect.bottom(),so.rect.right(),so.rect.bottom()); + painter->restore(); +} + +void ObjectInspectorWidget::mousePressEvent(QMouseEvent *event) +{ + + if ((event->button()==Qt::LeftButton)){ + QModelIndex index=indexAt(event->pos()); + if (index.isValid()){ + if (event->pos().x()isHaveValue()) + setExpanded(index,!isExpanded(index)); + } else { + if ((index.column()==1)&&(!nodeFromIndex(index)->isHaveChildren())) { + setCurrentIndex(index); + edit(index); + return ; + } + } + } + } + + QTreeView::mousePressEvent(event); +} + +void ObjectInspectorWidget::initColorMap() +{ + m_colors.reserve(6); + m_colors.push_back(QColor(255,230,191)); + m_colors.push_back(QColor(255,255,191)); + m_colors.push_back(QColor(191,255,191)); + m_colors.push_back(QColor(199,255,255)); + m_colors.push_back(QColor(234,191,255)); + m_colors.push_back(QColor(255,191,239)); +} + +QColor ObjectInspectorWidget::getColor(const int index) const +{ + return m_colors[index]; +} + +void ObjectInspectorWidget::reset() +{ + QTreeView::reset(); + for (int i=0;irowCount();i++){ + if (!nodeFromIndex(model()->index(i,0))->isHaveValue()){ + setFirstColumnSpanned(i,model()->index(i,0).parent(),true); + } + } +} + +ObjectPropItem * ObjectInspectorWidget::nodeFromIndex(QModelIndex index) const +{ + return static_cast(index.internalPointer()); +} + +void ObjectInspectorWidget::keyPressEvent(QKeyEvent *event) +{ + if (event->key()==Qt::Key_Return){ + if(!m_propertyDelegate->isEditing()){ + QModelIndex index = currentIndex().model()->index(currentIndex().row(), + 1,currentIndex().parent()); + edit(index); + event->accept(); + } + } else QTreeView::keyPressEvent(event); +} + +void ObjectInspectorWidget::commitActiveEditorData(){ + if (state()==QAbstractItemView::EditingState){ + commitData(indexWidget(currentIndex())); + } +} + +} //namespace LimeReport diff --git a/src/objectinspector/lrobjectinspectorwidget.h b/src/objectinspector/lrobjectinspectorwidget.h new file mode 100644 index 0000000..d6e4495 --- /dev/null +++ b/src/objectinspector/lrobjectinspectorwidget.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LROBJECTINSPECTORWIDGET_H +#define LROBJECTINSPECTORWIDGET_H + +#include +#include +#include "lrobjectitemmodel.h" +#include "lrpropertydelegate.h" + +namespace LimeReport{ + +class ObjectInspectorWidget : public QTreeView +{ + Q_OBJECT +public: + ObjectInspectorWidget(QWidget * parent=0); + ~ObjectInspectorWidget(); + QColor getColor(const int index) const; + virtual void reset(); + virtual void commitActiveEditorData(); +protected: + void mousePressEvent(QMouseEvent *event); + void drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const; + void keyPressEvent(QKeyEvent *event); +private: + void initColorMap(); + LimeReport::ObjectPropItem* nodeFromIndex(QModelIndex index) const; + +private: + QVector m_colors; + PropertyDelegate *m_propertyDelegate; +}; + +} //namespace LimeReport + +#endif // LROBJECTINSPECTORWIDGET_H diff --git a/src/objectinspector/lrobjectitemmodel.cpp b/src/objectinspector/lrobjectitemmodel.cpp new file mode 100644 index 0000000..7b837b8 --- /dev/null +++ b/src/objectinspector/lrobjectitemmodel.cpp @@ -0,0 +1,357 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrobjectitemmodel.h" +#include +#include +#include +#include + +namespace LimeReport { + +QObjectPropertyModel::QObjectPropertyModel(QObject *parent/*=0*/) + :QAbstractItemModel(parent),m_rootNode(0),m_object(0),m_dataChanging(false), m_subclassesAsLevel(true), m_validator(0) +{} + +QObjectPropertyModel::~QObjectPropertyModel() +{ + if (m_rootNode) + delete m_rootNode; +} + +void QObjectPropertyModel::initModel() +{ + beginResetModel(); + delete m_rootNode; + m_rootNode=0; + if (m_object) { + connect(m_object,SIGNAL(destroyed(QObject*)),this,SLOT(slotObjectDestroyed(QObject*))); + m_rootNode=new ObjectPropItem(0,0,"root","root",QVariant(),0); + m_rootNode->setModel(this); + foreach(QObject* item, m_objects) + connect(item,SIGNAL(destroyed(QObject*)),this,SLOT(slotObjectDestroyed(QObject*))); + addObjectProperties(m_object->metaObject(), m_object, &m_objects); + } + //reset(); + endResetModel(); +} + +void QObjectPropertyModel::setObject(QObject *object) +{ + m_objects.clear(); + if (m_object!=object){ + submit(); + m_object=object; + initModel(); + } +} + +void QObjectPropertyModel::setMultiObjects(QList* list) +{ + m_objects.clear(); + submit(); + if (m_object!=list->at(0)){ + m_object=list->at(0); + list->removeAt(0); + foreach(QObject* item, *list) + m_objects.append(item); + initModel(); + } + +} + +void QObjectPropertyModel::slotObjectDestroyed(QObject *obj) +{ + m_objects.removeOne(obj); + if (m_object == obj){ + m_object=0; + if (!m_objects.isEmpty()) m_object=m_objects.at(0); + initModel(); + } +} + +void QObjectPropertyModel::slotPropertyChanged(const QString &propertyName, const QVariant& oldValue, const QVariant& newValue) +{ + Q_UNUSED(oldValue); + Q_UNUSED(newValue); + if (m_object) + updateProperty(propertyName); +} + +void QObjectPropertyModel::slotPropertyObjectNameChanged(const QString &oldName, const QString &newName) +{ + Q_UNUSED(oldName) + Q_UNUSED(newName) + if (m_object) + updateProperty("objectName"); +} + + +int QObjectPropertyModel::columnCount(const QModelIndex &/*parent*/) const +{ + return 2; +} + +QVariant QObjectPropertyModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(orientation==Qt::Horizontal&&role==Qt::DisplayRole){ + if (section==0) return tr("Property Name"); + else return tr("Property value"); + } else return QVariant(); +} + +ObjectPropItem * QObjectPropertyModel::nodeFromIndex(const QModelIndex &index) const +{ + if(index.isValid()){ + return static_cast(index.internalPointer()); + } else return m_rootNode; +} + +void QObjectPropertyModel::updateProperty(const QString &propertyName) +{ + if (!m_dataChanging&&m_rootNode){ + ObjectPropItem* propItem = m_rootNode->findPropertyItem(propertyName); + if (propItem) + propItem->updatePropertyValue(); + } +} + +void QObjectPropertyModel::setSubclassesAsLevel(bool value) +{ + m_subclassesAsLevel = value; +} + +int QObjectPropertyModel::rowCount(const QModelIndex &parent) const +{ + if (!m_rootNode) return 0; + ObjectPropItem *parentNode; + if (parent.isValid()) + parentNode = nodeFromIndex(parent); + else + parentNode = m_rootNode; + return parentNode->childCount(); +} + +QVariant QObjectPropertyModel::data(const QModelIndex &index, int role) const +{ + ObjectPropItem *node = nodeFromIndex(index); + switch (role) { + case Qt::DisplayRole: + if (!node) return QVariant(); + if (index.column()==0){ + return node->displayName(); + } else return node->displayValue(); + break; + case Qt::DecorationRole : + if (!node) return QIcon(); + if (index.column()==1){ + return node->iconValue(); + }else return QIcon(); + break; + default: + return QVariant(); + } +} + +QModelIndex QObjectPropertyModel::index(int row, int column, const QModelIndex &parent) const +{ + if(!m_rootNode) + return QModelIndex(); + + if (!hasIndex(row, column, parent)) + return QModelIndex(); + + ObjectPropItem *parentNode; + if (parent.isValid()) + parentNode = nodeFromIndex(parent); + else + parentNode = m_rootNode; + + ObjectPropItem *childItem=parentNode->child(row); + + if (childItem){ + QModelIndex modelIndex=createIndex(row,column,childItem); + if (column==1){ + if (childItem->modelIndex()!=modelIndex){ + childItem->setModelIndex(modelIndex); + } + } + return modelIndex; + } + else return QModelIndex(); +} + +QModelIndex QObjectPropertyModel::parent(const QModelIndex &child) const +{ + if (!child.isValid()) return QModelIndex(); + + ObjectPropItem *childNode = nodeFromIndex(child); + if (!childNode) return QModelIndex(); + + ObjectPropItem *parentNode = childNode->parent(); + if ((parentNode == m_rootNode) || (!parentNode)) return QModelIndex(); + + return createIndex(parentNode->row(),0,parentNode); +} + + +Qt::ItemFlags QObjectPropertyModel::flags(const QModelIndex &index) const +{ + if ((index.column()==1)&&(!nodeFromIndex(index)->isValueReadonly())) return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable; + else return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +CreatePropItem QObjectPropertyModel::propertyItemCreator(QMetaProperty prop) +{ + CreatePropItem creator=0; + creator=ObjectPropFactory::instance().objectCreator(APropIdent(prop.name(),prop.enclosingMetaObject()->className())); + if (!creator){ + if (prop.isFlagType()){ + creator=ObjectPropFactory::instance().objectCreator(APropIdent("flags","")); + if (creator){ + return creator; + } else { + qDebug()<<"flags prop editor not found"; + return 0; + } + } + if (prop.isEnumType()){ + creator=ObjectPropFactory::instance().objectCreator(APropIdent("enum","")); + if (creator){ + return creator; + } else { + qDebug()<<"enum prop editor not found"; + return 0; + } + } + creator=ObjectPropFactory::instance().objectCreator(APropIdent(prop.typeName(),"")); + if (!creator) {qDebug()<<"Editor for propperty name = \""<property(prop.name()), + parent, + !(prop.isWritable()&&prop.isDesignable()) + ); + } else { + propertyItem=new ObjectPropItem( + 0, + 0, + QString(prop.name()), + QString(prop.name()), + object->property(prop.name()), + parent + ); + } + return propertyItem; +} +ValidatorIntf *QObjectPropertyModel::validator() const +{ + return m_validator; +} + +void QObjectPropertyModel::setValidator(ValidatorIntf *validator) +{ + m_validator = validator; +} + + +void QObjectPropertyModel::addObjectProperties(const QMetaObject *metaObject, QObject *object, ObjectPropItem::ObjectsList *objects, int level) +{ + if (metaObject->propertyCount()>metaObject->propertyOffset()){ + ObjectPropItem* objectNode; + if (m_subclassesAsLevel){ + objectNode=new ObjectPropItem(0,0,metaObject->className(),metaObject->className(),m_rootNode,true); + m_rootNode->appendItem(objectNode); + } else { + objectNode = m_rootNode; + } + + //m_rootNode->appendItem(objectNode); + + for (int i=metaObject->propertyOffset();ipropertyCount();i++){ + if (metaObject->property(i).isDesignable()){ + ObjectPropItem* prop=createPropertyItem(metaObject->property(i),object,objects,objectNode); + //ObjectPropItem* prop=createPropertyItem(metaObject->property(i),object,objects,m_rootNode); + //m_rootNode->appendItem(prop); + objectNode->appendItem(prop); + } + } + if (m_subclassesAsLevel){ + objectNode->setColorIndex(level); + objectNode->sortItem(); + level++; + } + } + + if (metaObject->superClass()) addObjectProperties(metaObject->superClass(),object,objects,level); + m_rootNode->sortItem(); +} + +bool QObjectPropertyModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (index.isValid()&&role==Qt::EditRole){ + m_dataChanging=true; + ObjectPropItem * propItem = nodeFromIndex(index); + if (propItem->propertyValue()!=value){ + QString msg; + if (validator() && !validator()->validate(propItem->propertyName(),value.toString(),m_object,msg)){ + QMessageBox::information(0,tr("Warning"),msg); + return true; + } + QVariant oldValue=propItem->propertyValue(); + propItem->setPropertyValue(value); + emit dataChanged(index,index); + emit objectPropetyChanged(propItem->propertyName(),oldValue,propItem->propertyValue()); + } + m_dataChanging=false; + return true; + } + return false; +} + +void QObjectPropertyModel::itemDataChanged(const QModelIndex &index) +{ + emit dataChanged(index,index); +} + +} + diff --git a/src/objectinspector/lrobjectitemmodel.h b/src/objectinspector/lrobjectitemmodel.h new file mode 100644 index 0000000..b354538 --- /dev/null +++ b/src/objectinspector/lrobjectitemmodel.h @@ -0,0 +1,94 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LROBJECTITEMMODEL_H +#define LROBJECTITEMMODEL_H + +#include +#include +#include +#include "lrobjectpropitem.h" + +namespace LimeReport{ + + +class ValidatorIntf { +public: + virtual bool validate(const QString& propName, const QVariant& propValue, QObject* object, QString& msg) = 0; + virtual ~ValidatorIntf(){} +}; + +class QObjectPropertyModel : public QAbstractItemModel +{ + Q_OBJECT +public: + QObjectPropertyModel(QObject *parent=0); + ~QObjectPropertyModel(); + virtual void setObject(QObject *object); + virtual void setMultiObjects(QList* list); + virtual QModelIndex index(int row, int column, const QModelIndex &parent) const; + virtual QModelIndex parent(const QModelIndex &child) const; + virtual int columnCount(const QModelIndex &parent) const; + virtual int rowCount(const QModelIndex &parent) const; + virtual QVariant data(const QModelIndex &index, int role) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + virtual bool setData(const QModelIndex &index, const QVariant &value, int role); + void itemDataChanged(const QModelIndex &index); + void initModel(); + const QObject* currentObject(){return m_object;} + LimeReport::ObjectPropItem* nodeFromIndex(const QModelIndex &index) const; + LimeReport::ObjectPropItem* rootNode(){return m_rootNode;} + void updateProperty(const QString& propertyName); + void setSubclassesAsLevel(bool value); + bool subclassesAsLevel(){return m_subclassesAsLevel;} + ValidatorIntf* validator() const; + void setValidator(ValidatorIntf* validator); + +signals: + void objectPropetyChanged(const QString& , const QVariant&, const QVariant&); +private slots: + void slotObjectDestroyed(QObject* obj); + void slotPropertyChanged(const QString& propertyName, const QVariant &oldValue, const QVariant &newValue); + void slotPropertyObjectNameChanged(const QString& oldName, const QString& newName); +private: + void addObjectProperties(const QMetaObject *metaObject, QObject *object, ObjectPropItem::ObjectsList* objects, int level=0); + LimeReport::CreatePropItem propertyItemCreator(QMetaProperty prop); + LimeReport::ObjectPropItem* createPropertyItem(QMetaProperty prop, QObject *object, ObjectPropItem::ObjectsList* objects, ObjectPropItem* parent); +private: + LimeReport::ObjectPropItem* m_rootNode; + QObject* m_object; + QList m_objects; + bool m_dataChanging; + bool m_subclassesAsLevel; + ValidatorIntf* m_validator; +}; + +} +#endif // LROBJECTITEMMODEL_H diff --git a/src/objectinspector/lrobjectpropitem.cpp b/src/objectinspector/lrobjectpropitem.cpp new file mode 100644 index 0000000..a13751d --- /dev/null +++ b/src/objectinspector/lrobjectpropitem.cpp @@ -0,0 +1,181 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrobjectpropitem.h" +#include "lrobjectitemmodel.h" +#ifdef INSPECT_BASEDESIGN +#include "lrbasedesignintf.h" +#endif +#include + +namespace LimeReport { + +bool lesThen(ObjectPropItem* v1, ObjectPropItem* v2){ + return v1->displayName().compare(v2->displayName())<0; +} + +ObjectPropItem::ObjectPropItem(QObject *object, ObjectsList* objects, const QString &name, const QString &displayName, ObjectPropItem *parent, bool isClass) + :m_object(object), m_name(name), m_displayName(displayName), m_haveValue(false), m_parent(parent), m_colorIndex(-1), + m_readonly(true), m_model(0), m_isClass(isClass), m_changingValue(false) +{ + if (parent) setModel(parent->model()); + m_index=QModelIndex(); + if (objects) foreach(QObject* item, *objects) m_objects.append(item); +#ifdef INSPECT_BASEDESIGN + BaseDesignIntf * item = dynamic_cast(object); + if (item){ + connect(item,SIGNAL(propertyChanged(QString,QVariant,QVariant)),this,SLOT(slotPropertyChanged(QString,QVariant,QVariant))); + connect(item,SIGNAL(propertyObjectNameChanged(QString,QString)),this,SLOT(slotPropertyObjectName(QString,QString))); + } +#endif +} + +ObjectPropItem::ObjectPropItem(QObject *object, ObjectsList* objects, const QString &name, const QString &displayName, const QVariant &value, ObjectPropItem *parent, bool readonly) + :m_object(object), m_name(name), m_displayName(displayName), m_value(value), + m_haveValue(true), m_parent(parent), m_colorIndex(-1), + m_readonly(readonly), m_model(0), m_isClass(false), m_changingValue(false) +{ + if (parent) setModel(parent->model()); + m_index=QModelIndex(); + if (objects) foreach(QObject* item, *objects) m_objects.append(item); +#ifdef INSPECT_BASEDESIGN + BaseDesignIntf * item = dynamic_cast(object); + if (item){ + connect(item,SIGNAL(propertyChanged(QString,QVariant,QVariant)),this,SLOT(slotPropertyChanged(QString,QVariant,QVariant))); + connect(item,SIGNAL(propertyObjectNameChanged(QString,QString)),this,SLOT(slotPropertyObjectName(QString,QString))); + } +#endif +} + +ObjectPropItem::~ObjectPropItem(){ + qDeleteAll(m_childItems); +} + + +int ObjectPropItem::childCount(){ + return m_childItems.count(); +} + +void ObjectPropItem::appendItem(ObjectPropItem *item){ + m_childItems.append(item); + if (m_parent && (!item->isClass())) m_parent->m_globalPropList.append(item); +} + +void ObjectPropItem::sortItem() +{ + qSort(m_childItems.begin(), m_childItems.end(), lesThen); +} + +QVariant ObjectPropItem::propertyValue() const { + return m_value; +} + +void ObjectPropItem::setPropertyValue(QVariant value){ + m_value=value; + LimeReport::QObjectPropertyModel *itemModel=dynamic_cast(model()); + if (itemModel){ + itemModel->itemDataChanged(modelIndex()); + foreach(ObjectPropItem*item, children()){ + if (item->modelIndex().isValid()) itemModel->itemDataChanged(item->modelIndex()); + } + } +} + +int ObjectPropItem::row(){ + if (m_parent) + return m_parent->m_childItems.indexOf(const_cast(this)); + return 0; +} + +ObjectPropItem * ObjectPropItem::child(int row){ + return m_childItems[row]; +} + +void ObjectPropItem::setColorIndex(int value) +{ + m_colorIndex=value; + for (int i=0;isetColorIndex(value); + } +} + +#ifdef INSPECT_BASEDESIGN +void ObjectPropItem::slotPropertyChanged(const QString &name, QVariant, QVariant newValue) +{ + if (name.compare(propertyName(),Qt::CaseInsensitive)==0 && !isValueChanging()){ + setPropertyValue(newValue); + } +} + +void ObjectPropItem::slotPropertyObjectName(const QString &oldValue, const QString &newValue) +{ + Q_UNUSED(oldValue) + if (propertyName().compare("objectName",Qt::CaseInsensitive)==0 && !isValueChanging()){ + setPropertyValue(newValue); + } +} +#endif + +ObjectPropItem * ObjectPropItem::findChild(const QString &name) +{ + foreach(ObjectPropItem* item,m_childItems){ + if (item->propertyName()==name) return item; + } + return 0; +} + +ObjectPropItem *ObjectPropItem::findPropertyItem(const QString &propertyName) +{ + foreach(ObjectPropItem* item,m_globalPropList){ + if (item->propertyName()==propertyName) return item; + } + return 0; +} + +void ObjectPropItem::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const +{ + editor->setGeometry(option.rect); +} + +void ObjectPropItem::updatePropertyValue() +{ + m_model->setData(m_index,m_object->property(m_name.toLatin1())); +} + +bool ObjectPropItem::paint(QPainter *, const QStyleOptionViewItemV4 &, const QModelIndex &) +{ + return false; +} + +QString ObjectPropItem::displayValue() const +{ + return m_value.toString(); +} + +} diff --git a/src/objectinspector/lrobjectpropitem.h b/src/objectinspector/lrobjectpropitem.h new file mode 100644 index 0000000..b70976a --- /dev/null +++ b/src/objectinspector/lrobjectpropitem.h @@ -0,0 +1,139 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LROBJECTPROPITEM_H +#define LROBJECTPROPITEM_H + +#include +#include +#include +#include +#include +#include +#include + +#include "lrattribsabstractfactory.h" +#include "lrsingleton.h" + +namespace LimeReport{ + + class ObjectPropItem : public QObject + { + Q_OBJECT + + public: + typedef QList< QObject* > ObjectsList; + ObjectPropItem(){invalidate();} + ObjectPropItem(QObject *object, ObjectsList* objects, const QString& propertyName, const QString& displayName, const QVariant& propertyValue, ObjectPropItem* parent, bool readonly=true); + ObjectPropItem(QObject *object, ObjectsList* objects, const QString& propertyName, const QString& displayName, ObjectPropItem *parent, bool isClass = false); + ~ObjectPropItem(); + + virtual QVariant propertyValue() const; + virtual void setPropertyValue(QVariant value); + virtual QString propertyName() const {return m_name;} + virtual QString displayName() const {return m_displayName;} + virtual QString displayValue() const; + virtual QIcon iconValue() const{return QIcon();} + virtual bool isHaveChildren() const {return m_childItems.count()>0;} + virtual bool isHaveValue() const {return m_haveValue;} + virtual bool isValueReadonly() const {return m_readonly;} + void setValueReadOnly(bool value){m_readonly=value;} + virtual bool isValueModified() const {return false;} + virtual QWidget* createProperyEditor(QWidget * /*parent*/) const {return 0;} + virtual void setPropertyEditorData(QWidget *, const QModelIndex &) const{} + virtual void setModelData(QWidget * /*editor*/, QAbstractItemModel * /*model*/, const QModelIndex &/*index*/){} + virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/*index*/) const; + virtual void updatePropertyValue(); + virtual bool paint(QPainter *, const QStyleOptionViewItemV4 &, const QModelIndex &); + + ObjectPropItem* parent() const{ return m_parent;} + QObject* object() const{return m_object;} + ObjectsList* objects() {return &m_objects;} + ObjectPropItem* child(int row); + QList children(){return m_childItems;} + ObjectPropItem* findChild(const QString& propertyName); + ObjectPropItem* findPropertyItem(const QString& propertyName); + int childCount(); + void appendItem(ObjectPropItem* item); + void sortItem(); + int row(); + bool isValid(){return m_valid;} + int colorIndex(){return m_colorIndex;} + void setColorIndex(int propertyValue); + void setModel(QAbstractItemModel* model){m_model=model;} + QAbstractItemModel* model(){return m_model;} + void setModelIndex(QModelIndex index){m_index=index;} + QModelIndex modelIndex(){return m_index;} + bool isClass(){return m_isClass;} +#ifdef INSPECT_BASEDESIGN + private slots: + void slotPropertyChanged(const QString& name, QVariant, QVariant newValue); + void slotPropertyObjectName(const QString& oldValue, const QString& newValue); +#endif + private: + bool m_valid; + void invalidate(){m_object=0; m_valid = false; m_name = ""; m_value=QVariant(), m_isClass=false;} + protected: + void beginChangeValue(){ m_changingValue = true; } + void endChangeValue(){ m_changingValue = false; } + bool isValueChanging(){ return m_changingValue; } + private: + QObject* m_object; + ObjectsList m_objects; + QString m_name; + QString m_displayName; + QVariant m_value; + bool m_haveValue; + ObjectPropItem* m_parent; + QList m_childItems; + QList m_globalPropList; + int m_colorIndex; + bool m_readonly; + QAbstractItemModel* m_model; + QModelIndex m_index; + bool m_isClass; + bool m_changingValue; + }; + + typedef QPair APropIdent; + typedef ObjectPropItem* (*CreatePropItem)(QObject *object, ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value, ObjectPropItem* parent, bool readonly); + + class ObjectPropFactory : public AttribsAbstractFactory + { + private: + friend class Singleton; + private: + ObjectPropFactory(){} + ~ObjectPropFactory(){} + ObjectPropFactory(const ObjectPropFactory&){} + ObjectPropFactory& operator = (const ObjectPropFactory&){return *this;} + }; + +} +#endif // LROBJECTPROPITEM_H diff --git a/src/objectinspector/lrpropertydelegate.cpp b/src/objectinspector/lrpropertydelegate.cpp new file mode 100644 index 0000000..4796c23 --- /dev/null +++ b/src/objectinspector/lrpropertydelegate.cpp @@ -0,0 +1,165 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrpropertydelegate.h" +#include "lrobjectitemmodel.h" +#include "lrobjectinspectorwidget.h" +#include +#include +#include +#include "lrglobal.h" + +LimeReport::PropertyDelegate::PropertyDelegate(QObject *parent) + :QItemDelegate(parent), m_editingItem(0), m_isEditing(false) + //:QStyledItemDelegate(parent), m_editingItem(0) +{ + //setClipping(false); +} + +void LimeReport::PropertyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if (!index.isValid()) return; + + LimeReport::ObjectPropItem *node = static_cast(index.internalPointer()); + if (node){ + if (!node->isHaveValue()){ + if (index.column()==0) { + QStyleOptionViewItemV4 cellOpt = option; + QTreeView const *tree = dynamic_cast(cellOpt.widget); + QStyleOptionViewItem primitiveOpt = cellOpt; + primitiveOpt.rect.setWidth(tree->indentation()); + painter->save(); + painter->setPen(option.palette.color(QPalette::HighlightedText)); + painter->setBackground(QBrush(option.palette.color(QPalette::Highlight))); + drawBackground(painter,option,index); + cellOpt.widget->style()->drawPrimitive(QStyle::PE_IndicatorBranch,&primitiveOpt,painter); + cellOpt.rect.adjust(primitiveOpt.rect.width(),0,0,0); + cellOpt.font.setBold(true); + cellOpt.palette.setColor(QPalette::Text,cellOpt.palette.color(QPalette::BrightText)); + drawDisplay(painter,cellOpt,cellOpt.rect,LimeReport::extractClassName(node->propertyName())); + painter->restore(); + } + } else + { + if (index.column()==0){ + QPointF start( + option.rect.x()+option.rect.width()-1, + option.rect.y() + ); + QPointF end( + option.rect.x()+option.rect.width()-1, + option.rect.y()+option.rect.height() + ); + painter->save(); + painter->setPen(option.palette.color(QPalette::Dark)); + painter->drawLine(start,end); + painter->restore(); + } + + QStyleOptionViewItemV4 so = option; + if ((node->isValueReadonly())&&(!node->isHaveChildren())) { + so.palette.setColor(QPalette::Text,so.palette.color(QPalette::Dark)); + } + drawBackground(painter,option,index); + if (!node->paint(painter,so,index)) + QItemDelegate::paint(painter, so, index); + } + } +} + +QSize LimeReport::PropertyDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &/*index*/) const +{ + QSize size=option.rect.size(); + size.setHeight(option.fontMetrics.height()+ + QApplication::style()->pixelMetric(QStyle::PM_ButtonMargin) +#ifdef Q_OS_MAC + +QApplication::style()->pixelMetric(QStyle::PM_FocusFrameVMargin) +#endif + +2); + return size; +} + +QWidget * LimeReport::PropertyDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + m_editingItem=static_cast(index.internalPointer()); + connect(m_editingItem,SIGNAL(destroyed(QObject*)), this, SLOT(slotItemDeleted(QObject*))); + QWidget *editor=m_editingItem->createProperyEditor(parent); + if (editor){ + m_isEditing = true; + editor->setMaximumHeight(option.rect.height()-1); + editor->setGeometry(option.rect); + if (editor->metaObject()->indexOfSignal("editingFinished()")!=-1) + connect(editor,SIGNAL(editingFinished()),this,SLOT(commitAndCloseEditor())); + connect(editor,SIGNAL(destroyed()),this,SLOT(slotEditorDeleted())); + } + return editor; +} + +void LimeReport::PropertyDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + if (m_editingItem) m_editingItem->setPropertyEditorData(editor,index); +} + +void LimeReport::PropertyDelegate::commitAndCloseEditor() +{ + QWidget *editor = qobject_cast(sender()); + emit commitData(editor); + emit closeEditor(editor); +} + +void LimeReport::PropertyDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + if (m_editingItem) m_editingItem->setModelData(editor,model,index); +} + +void LimeReport::PropertyDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if (m_editingItem) m_editingItem->updateEditorGeometry(editor,option,index); +} + +void LimeReport::PropertyDelegate::setObjectInspector(ObjectInspectorWidget* objectInspector) +{ + m_objectInspector=objectInspector; +} + +void LimeReport::PropertyDelegate::slotEditorDeleted() +{ + m_isEditing=false; +} + +void LimeReport::PropertyDelegate::slotItemDeleted(QObject *item) +{ + if (item == m_editingItem) m_editingItem = 0; +} + +LimeReport::ObjectPropItem* LimeReport::PropertyDelegate::editingItem() +{ + return m_editingItem; +} + diff --git a/src/objectinspector/lrpropertydelegate.h b/src/objectinspector/lrpropertydelegate.h new file mode 100644 index 0000000..f7e2414 --- /dev/null +++ b/src/objectinspector/lrpropertydelegate.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRPROPERTYDELEGATE_H +#define LRPROPERTYDELEGATE_H + +#include +#include +#include +#include + +#include "lrobjectitemmodel.h" + +namespace LimeReport{ + +class ObjectInspectorWidget; +class PropertyDelegate : public QItemDelegate +//class PropertyDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + PropertyDelegate(QObject *parent=0); + void setObjectInspector(ObjectInspectorWidget* objectInspector); + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; + QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; + void setEditorData(QWidget *editor, const QModelIndex &index) const; + void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; + LimeReport::ObjectPropItem* editingItem(); + bool isEditing(){return m_isEditing;} +private slots: + void commitAndCloseEditor(); + void slotEditorDeleted(); + void slotItemDeleted(QObject* item); +private: + LimeReport::ObjectInspectorWidget* m_objectInspector; + mutable LimeReport::ObjectPropItem* m_editingItem; + mutable bool m_isEditing; +}; +} +#endif // LRPROPERTYDELEGATE_H diff --git a/src/objectinspector/propertyItems/lrboolpropitem.cpp b/src/objectinspector/propertyItems/lrboolpropitem.cpp new file mode 100644 index 0000000..7c7f167 --- /dev/null +++ b/src/objectinspector/propertyItems/lrboolpropitem.cpp @@ -0,0 +1,92 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrboolpropitem.h" +#include "lrobjectpropitem.h" +#include +#include +#include +#include + +#include "../editors/lrcheckboxeditor.h" + +namespace{ + LimeReport::ObjectPropItem * createBoolPropItem( + QObject *object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly) + { + return new LimeReport::BoolPropItem(object, objects, name, displayName, data, parent, readonly); + } + bool registred = LimeReport::ObjectPropFactory::instance().registerCreator(LimeReport::APropIdent("bool",""),QObject::tr("bool"),createBoolPropItem); +} // namespace + +namespace LimeReport { + +QWidget *BoolPropItem::createProperyEditor(QWidget *parent) const +{ + CheckBoxEditor *editor= new CheckBoxEditor(parent); + return editor; +} + +void BoolPropItem::setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const +{ + CheckBoxEditor *editor =qobject_cast(propertyEditor); + editor->setEditing(true); + editor->setChecked(propertyValue().toBool()); + editor->setEditing(false); +} + +void BoolPropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index) +{ + model->setData(index,qobject_cast(propertyEditor)->isChecked()); + object()->setProperty(propertyName().toLatin1(),propertyValue()); +} + +bool BoolPropItem::paint(QPainter *painter, const QStyleOptionViewItemV4 &option, const QModelIndex &index) +{ + if (index.column()==1){ + QStyleOptionButton so; + int border = (option.rect.height() - QApplication::style()->pixelMetric(QStyle::PM_IndicatorWidth))/2; + so.rect = option.rect.adjusted(border,border,0,-border); + so.rect.setWidth(QApplication::style()->pixelMetric(QStyle::PM_IndicatorWidth)); + + if (!isValueReadonly()) + so.state = QStyle::State_Enabled; + else + so.state &= ~QStyle::State_Enabled; + + so.state |= propertyValue().toBool() ? QStyle::State_On : QStyle::State_Off; + + option.widget->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox,&so,painter); + + return true; + } else return false; +} + +} // namespace LimeReport + diff --git a/src/objectinspector/propertyItems/lrboolpropitem.h b/src/objectinspector/propertyItems/lrboolpropitem.h new file mode 100644 index 0000000..0e7dc99 --- /dev/null +++ b/src/objectinspector/propertyItems/lrboolpropitem.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRBOOLPROPITEM_H +#define LRBOOLPROPITEM_H + +#include "lrobjectpropitem.h" + +namespace LimeReport { +class BoolPropItem : public ObjectPropItem +{ + Q_OBJECT +public: + BoolPropItem():ObjectPropItem(){} + BoolPropItem(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value, ObjectPropItem* parent, bool readonly) + :ObjectPropItem(object, objects, name, displayName, value, parent, readonly){} + virtual QString displayValue() const {return "";} + virtual QWidget* createProperyEditor(QWidget *parent) const; + virtual void setPropertyEditorData(QWidget * propertyEditor, const QModelIndex &) const; + virtual void setModelData(QWidget * propertyEditor, QAbstractItemModel * model, const QModelIndex & index); + bool paint(QPainter *painter, const QStyleOptionViewItemV4 &option, const QModelIndex &index); +}; +} // namespace LimeReport + +#endif // LRBOOLPROPITEM_H diff --git a/src/objectinspector/propertyItems/lrcolorpropitem.cpp b/src/objectinspector/propertyItems/lrcolorpropitem.cpp new file mode 100644 index 0000000..5532e4f --- /dev/null +++ b/src/objectinspector/propertyItems/lrcolorpropitem.cpp @@ -0,0 +1,76 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrcolorpropitem.h" +#include "editors/lrcoloreditor.h" +#include + +namespace{ + LimeReport::ObjectPropItem * createColorPropItem( + QObject *object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly) + { + return new LimeReport::ColorPropItem(object, objects, name, displayName, data, parent, readonly); + } + bool registredColorProp = LimeReport::ObjectPropFactory::instance().registerCreator(LimeReport::APropIdent("QColor",""),QObject::tr("QColor"),createColorPropItem); +} + +namespace LimeReport{ + +void ColorPropItem::setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const +{ + ColorEditor *editor =qobject_cast(propertyEditor); + editor->setColor(propertyValue().value()); +} + +void ColorPropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index) +{ + model->setData(index,qobject_cast(propertyEditor)->color()); + object()->setProperty(propertyName().toLatin1(),propertyValue()); +} + +bool ColorPropItem::paint(QPainter *painter, const QStyleOptionViewItemV4 &option, const QModelIndex &index) +{ + if (index.column()==1){ + painter->save(); + painter->setBrush(propertyValue().value()); + painter->setPen(Qt::gray); + QRect rect = option.rect.adjusted(4,4,-4,-6); + rect.setWidth(rect.height()); + painter->drawRect(rect); + painter->restore(); + return true; + } else return false; +} + +QWidget *ColorPropItem::createProperyEditor(QWidget *parent) const +{ + return new ColorEditor(parent); +} + +} diff --git a/src/objectinspector/propertyItems/lrcolorpropitem.h b/src/objectinspector/propertyItems/lrcolorpropitem.h new file mode 100644 index 0000000..f4940b5 --- /dev/null +++ b/src/objectinspector/propertyItems/lrcolorpropitem.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRCOLORPROPITEM_H +#define LRCOLORPROPITEM_H + +#include "lrobjectpropitem.h" + +namespace LimeReport{ + +class ColorPropItem : public ObjectPropItem +{ + Q_OBJECT +public: + ColorPropItem():ObjectPropItem(){} + ColorPropItem(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value,ObjectPropItem* parent, bool readonly) + :ObjectPropItem(object, objects, name, displayName, value, parent, readonly){} + QWidget* createProperyEditor(QWidget *parent) const; + void setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const; + void setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index); + bool paint(QPainter *painter, const QStyleOptionViewItemV4 &option, const QModelIndex &index); +}; + +} +#endif // LRCOLORPROPITEM_H diff --git a/src/objectinspector/propertyItems/lrdatasourcepropitem.cpp b/src/objectinspector/propertyItems/lrdatasourcepropitem.cpp new file mode 100644 index 0000000..e107edb --- /dev/null +++ b/src/objectinspector/propertyItems/lrdatasourcepropitem.cpp @@ -0,0 +1,103 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrdatasourcepropitem.h" +#include "lrobjectpropitem.h" +#include "lrbasedesignintf.h" +#include "lrreportengine_p.h" +#include "../editors/lrcomboboxeditor.h" +#include + +namespace{ + LimeReport::ObjectPropItem * createDatasourcePropItem( + QObject *object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly) + { + return new LimeReport::DatasourcePropItem(object, objects, name, displayName, data, parent, readonly); + } + + LimeReport::ObjectPropItem* createFieldPropItem(QObject *object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly){ + return new LimeReport::FieldPropItem(object, objects, name, displayName, data, parent, readonly); + } + + bool registredDatasouceProp = LimeReport::ObjectPropFactory::instance().registerCreator( + LimeReport::APropIdent("datasource","LimeReport::DataBandDesignIntf"),QObject::tr("datasource"),createDatasourcePropItem + ); + bool registredImageDatasouceProp = LimeReport::ObjectPropFactory::instance().registerCreator( + LimeReport::APropIdent("datasource","LimeReport::ImageItem"),QObject::tr("datasource"),createDatasourcePropItem + ); + bool registredImageFieldProp = LimeReport::ObjectPropFactory::instance().registerCreator( + LimeReport::APropIdent("field","LimeReport::ImageItem"),QObject::tr("field"),createFieldPropItem + ); +} + +QWidget* LimeReport::DatasourcePropItem::createProperyEditor(QWidget *parent) const{ + ComboBoxEditor *editor = new ComboBoxEditor(parent); + editor->setEditable(true); + LimeReport::BaseDesignIntf *item=dynamic_cast(object()); + if (item){ + editor->addItems(item->reportEditor()->dataManager()->dataSourceNames()); + } + return editor; +} + +void LimeReport::DatasourcePropItem::setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const{ + ComboBoxEditor *editor=qobject_cast(propertyEditor); + editor->setTextValue(propertyValue().toString()); +} + +void LimeReport::DatasourcePropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index){ + model->setData(index,qobject_cast(propertyEditor)->text()); + object()->setProperty(propertyName().toLatin1(),propertyValue()); +} + + +QWidget *LimeReport::FieldPropItem::createProperyEditor(QWidget *parent) const +{ + ComboBoxEditor *editor = new ComboBoxEditor(parent); + editor->setEditable(true); + LimeReport::BaseDesignIntf *item=dynamic_cast(object()); + int propertyIndex = object()->metaObject()->indexOfProperty("datasource"); + + if (item && propertyIndex>0){ + editor->addItems(item->reportEditor()->dataManager()->fieldNames(object()->property("datasource").toString())); + } + return editor; +} + +void LimeReport::FieldPropItem::setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const +{ + ComboBoxEditor *editor=qobject_cast(propertyEditor); + editor->setTextValue(propertyValue().toString()); +} + +void LimeReport::FieldPropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index) +{ + model->setData(index,qobject_cast(propertyEditor)->text()); + object()->setProperty(propertyName().toLatin1(),propertyValue()); +} diff --git a/src/objectinspector/propertyItems/lrdatasourcepropitem.h b/src/objectinspector/propertyItems/lrdatasourcepropitem.h new file mode 100644 index 0000000..60f7062 --- /dev/null +++ b/src/objectinspector/propertyItems/lrdatasourcepropitem.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRDATASOURCEPROPITEM_H +#define LRDATASOURCEPROPITEM_H + +#include "lrobjectpropitem.h" +namespace LimeReport{ + +class DatasourcePropItem : public LimeReport::ObjectPropItem +{ + Q_OBJECT + +public: + DatasourcePropItem(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value,ObjectPropItem* parent, bool readonly) + :ObjectPropItem(object, objects, name, displayName, value, parent, readonly){} + QWidget* createProperyEditor(QWidget *parent) const; + void setPropertyEditorData(QWidget *, const QModelIndex &) const; + void setModelData(QWidget *, QAbstractItemModel *, const QModelIndex &); +}; + +class FieldPropItem : public LimeReport::ObjectPropItem +{ + Q_OBJECT + +public: + FieldPropItem(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value,ObjectPropItem* parent, bool readonly) + :ObjectPropItem(object, objects, name, displayName, value, parent, readonly){} + QWidget* createProperyEditor(QWidget *parent) const; + void setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const; + void setModelData(QWidget *propertyEditor, QAbstractItemModel *, const QModelIndex &index); +}; + +} +#endif // LRDATASOURCEPROPITEM_H diff --git a/src/objectinspector/propertyItems/lrenumpropitem.cpp b/src/objectinspector/propertyItems/lrenumpropitem.cpp new file mode 100644 index 0000000..ab56e5d --- /dev/null +++ b/src/objectinspector/propertyItems/lrenumpropitem.cpp @@ -0,0 +1,107 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrenumpropitem.h" +#include "../editors/lrcomboboxeditor.h" +#include "lrbanddesignintf.h" + +namespace { + +LimeReport::ObjectPropItem * createEnumPropItem( + QObject *object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly) +{ + return new LimeReport::EnumPropItem(object, objects, name, displayName, data, parent, readonly); +} +bool registred = LimeReport::ObjectPropFactory::instance().registerCreator( + LimeReport::APropIdent("enum",""),QObject::tr("enum"),createEnumPropItem +); + +} + +namespace LimeReport { + +QWidget *EnumPropItem::createProperyEditor(QWidget *parent) const +{ + ComboBoxEditor *editor = new ComboBoxEditor(parent,false); + connect(editor,SIGNAL(currentIndexChanged(QString)),this,SLOT(slotEnumChanged(QString))); + + QStringList enumValues; + QMetaEnum propEnum = object()->metaObject()->property(object()->metaObject()->indexOfProperty(propertyName().toLatin1())).enumerator(); + for (int i=0;iaddItems(enumValues); + return editor; +} + +void EnumPropItem::slotEnumChanged(const QString &text) +{ + if ( nameByType(object()->property(propertyName().toLatin1()).toInt())!=text){ + beginChangeValue(); + object()->setProperty(propertyName().toLatin1(),typeByName(text)); + setPropertyValue(typeByName(text)); + endChangeValue(); + } +} + +void EnumPropItem::setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const +{ + ComboBoxEditor *editor=qobject_cast(propertyEditor); + editor->setTextValue(nameByType(propertyValue().toInt())); +} + +void EnumPropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index) +{ + object()->setProperty(propertyName().toLatin1(),typeByName(qobject_cast(propertyEditor)->text())); + model->setData(index,object()->property(propertyName().toLatin1())); +} + +QString EnumPropItem::nameByType(int value) const +{ + QMetaEnum propEnum = object()->metaObject()->property(object()->metaObject()->indexOfProperty(propertyName().toLatin1())).enumerator(); + return propEnum.valueToKey(value); +} + +int EnumPropItem::typeByName(const QString &value) const +{ + QMetaEnum propEnum = object()->metaObject()->property(object()->metaObject()->indexOfProperty(propertyName().toLatin1())).enumerator(); + return propEnum.keyToValue(value.toLatin1()); +} + +QString EnumPropItem::displayValue() const +{ + return nameByType((propertyValue().toInt())); +} + +} diff --git a/src/objectinspector/propertyItems/lrenumpropitem.h b/src/objectinspector/propertyItems/lrenumpropitem.h new file mode 100644 index 0000000..7cd23c1 --- /dev/null +++ b/src/objectinspector/propertyItems/lrenumpropitem.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRENUMPROPITEM_H +#define LRENUMPROPITEM_H + +#include "lrobjectpropitem.h" + +namespace LimeReport{ +class EnumPropItem : public ObjectPropItem +{ + Q_OBJECT +public: + EnumPropItem():ObjectPropItem(){} + EnumPropItem(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value,ObjectPropItem* parent, bool readonly) + :ObjectPropItem(object, objects, name, displayName, value, parent, readonly),m_settingValue(false){} + EnumPropItem(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value,ObjectPropItem* parent, bool readonly, QVector acceptableValues) + :ObjectPropItem(object, objects, name, displayName, value, parent, readonly),m_acceptableValues(acceptableValues),m_settingValue(false){} + QWidget* createProperyEditor(QWidget *parent) const; + QString displayValue() const; + void setPropertyEditorData(QWidget * propertyEditor, const QModelIndex &) const; + void setModelData(QWidget * propertyEditor, QAbstractItemModel * model, const QModelIndex & index); + QVector acceptableValues() const {return m_acceptableValues;} +protected: + QString nameByType(int propertyValue) const; + int typeByName(const QString& propertyValue) const; +private slots: + void slotEnumChanged(const QString& text); +private: + QVector m_acceptableValues; + bool m_settingValue; +}; +} +#endif // LRENUMPROPITEM_H diff --git a/src/objectinspector/propertyItems/lrflagspropitem.cpp b/src/objectinspector/propertyItems/lrflagspropitem.cpp new file mode 100644 index 0000000..edf4c86 --- /dev/null +++ b/src/objectinspector/propertyItems/lrflagspropitem.cpp @@ -0,0 +1,147 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrflagspropitem.h" +#include "lrenumpropitem.h" +#include "lrboolpropitem.h" +#include "../editors/lrcheckboxeditor.h" +#include "lrobjectitemmodel.h" +#include +#include +#include +#include +#include +#include + +namespace { + +LimeReport::ObjectPropItem * createFlagsPropItem( + QObject *object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly) +{ + return new LimeReport::FlagsPropItem(object, objects, name, displayName, data, parent, readonly); +} +bool registred = LimeReport::ObjectPropFactory::instance().registerCreator( + LimeReport::APropIdent("flags",""),QObject::tr("flags"),createFlagsPropItem +); + +} // namespace + +namespace LimeReport { + +void FlagsPropItem::createChildren() +{ + QMetaEnum propEnum = object()->metaObject()->property(object()->metaObject()->indexOfProperty(propertyName().toLatin1())).enumerator(); + for (int i=0;iappendItem(new LimeReport::FlagPropItem( + object(), objects(), QString(propEnum.key(i)), QString(propEnum.key(i)), + bool((propertyValue().toInt() & propEnum.keyToValue(propEnum.key(i)))==propEnum.keyToValue(propEnum.key(i))), + this, false + ) + ); + } +} + +void FlagsPropItem::updateChildren() +{ + QMetaEnum propEnum = object()->metaObject()->property(object()->metaObject()->indexOfProperty(propertyName().toLatin1())).enumerator(); + for (int i=0;isetPropertyValue(bool((propertyValue().toInt() & propEnum.keyToValue(propEnum.key(i)))==propEnum.keyToValue(propEnum.key(i)))); + } +} + +FlagsPropItem::FlagsPropItem(QObject *object, ObjectPropItem::ObjectsList *objects, const QString &name, const QString &displayName, const QVariant &value, ObjectPropItem *parent, bool readonly) + :ObjectPropItem(object, objects, name, displayName, value, parent, readonly) +{ + createChildren(); +} + +FlagsPropItem::FlagsPropItem(QObject *object, ObjectPropItem::ObjectsList *objects, const QString &name, const QString &displayName, const QVariant &value, ObjectPropItem *parent, bool readonly, QSet acceptableValues) + :ObjectPropItem(object, objects, name, displayName, value, parent, readonly),m_acceptableValues(acceptableValues){} + +QString FlagsPropItem::displayValue() const +{ + QString result; + QMetaEnum propEnum = object()->metaObject()->property(object()->metaObject()->indexOfProperty(propertyName().toLatin1())).enumerator(); + for (int i=0;i(propertyEditor); + editor->setChecked(propertyValue().toBool()); +} + +void FlagPropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index) +{ + bool value = qobject_cast(propertyEditor)->isChecked(); + model->setData(index,value); + int flags = object()->property(parent()->propertyName().toLatin1()).toInt(); + if (value) flags=flags | valueByName(displayName()); + else if (flags&valueByName(displayName())) flags=flags ^ valueByName(displayName()); + object()->setProperty(parent()->propertyName().toLatin1(),flags); + parent()->setPropertyValue(flags); +} + +int FlagPropItem::valueByName(const QString& typeName) +{ + QMetaEnum propEnum = object()->metaObject()->property(object()->metaObject()->indexOfProperty(parent()->propertyName().toLatin1())).enumerator(); + return propEnum.keyToValue(typeName.toLatin1()); +} + +} // namespace LimeReport + + diff --git a/src/objectinspector/propertyItems/lrflagspropitem.h b/src/objectinspector/propertyItems/lrflagspropitem.h new file mode 100644 index 0000000..7213d4d --- /dev/null +++ b/src/objectinspector/propertyItems/lrflagspropitem.h @@ -0,0 +1,71 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRFLAGSPROPEDITOR_H +#define LRFLAGSPROPEDITOR_H + +#include "lrobjectpropitem.h" +#include "lrboolpropitem.h" + +namespace LimeReport{ + +class FlagsPropItem : public ObjectPropItem +{ + Q_OBJECT +public: + FlagsPropItem():ObjectPropItem(){} + FlagsPropItem(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value,ObjectPropItem* parent, bool readonly); + FlagsPropItem(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value,ObjectPropItem* parent, bool readonly, QSet acceptableValues); + virtual QString displayValue() const; + virtual void setPropertyValue(QVariant propertyValue); +private slots: + void slotEnumChanged(QString); +private: + QSet m_acceptableValues; + QString nameByType(int propertyValue) const; + int typeByName(QString propertyValue) const; + void createChildren(); + void updateChildren(); +}; + +class FlagPropItem : public BoolPropItem{ +public: + FlagPropItem():BoolPropItem(){} + FlagPropItem(QObject* object, ObjectsList* objects, const QString& propName, const QString& displayName, const QVariant& propertyValue, ObjectPropItem* parent, bool readonly); + virtual void setPropertyEditorData(QWidget * propertyEditor, const QModelIndex & ) const; + virtual void setModelData(QWidget *, QAbstractItemModel *, const QModelIndex &); + virtual QString displayValue() const{return "";} +private: + int valueByName(const QString &typeName); +}; + + +} // namespace LimeReport + +#endif // LRFLAGSPROPEDITOR_H diff --git a/src/objectinspector/propertyItems/lrfontpropitem.cpp b/src/objectinspector/propertyItems/lrfontpropitem.cpp new file mode 100644 index 0000000..16f20c6 --- /dev/null +++ b/src/objectinspector/propertyItems/lrfontpropitem.cpp @@ -0,0 +1,159 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include +#include +#include + +#include "lrfontpropitem.h" +#include "editors/lrbuttonlineeditor.h" +#include "editors/lrfonteditor.h" +#include "editors/lrcheckboxeditor.h" +#include "lrobjectitemmodel.h" + +namespace{ + LimeReport::ObjectPropItem * createFontPropItem( + QObject *object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly) + { + return new LimeReport::FontPropItem(object, objects, name, displayName, data, parent, readonly); + } + bool registredFontProp = LimeReport::ObjectPropFactory::instance().registerCreator(LimeReport::APropIdent("QFont",""),QObject::tr("QFont"),createFontPropItem); +} + + +namespace LimeReport{ + +FontPropItem::FontPropItem(QObject *object, ObjectPropItem::ObjectsList *objects, const QString &name, const QString &displayName, const QVariant &value, ObjectPropItem *parent, bool readonly) + :ObjectPropItem(object, objects, name, displayName, value, parent, readonly) +{ + m_bold = new FontAttribPropItem(object,objects,"bold",tr("bold"),propertyValue().value().bold(),this,false); + m_italic = new FontAttribPropItem(object,objects,"italic",tr("italic"),propertyValue().value().italic(),this,false); + m_underline = new FontAttribPropItem(object,objects,"underline",tr("underline"),propertyValue().value().underline(),this,false); + m_pointSize = new FontPointSizePropItem(object,0,"pointSize",tr("size"),propertyValue().value().pointSize(),this,false); + m_family = new FontFamilyPropItem(object,0,"family",tr("family"),propertyValue().value(),this,false); + + this->appendItem(m_family); + this->appendItem(m_pointSize); + this->appendItem(m_bold); + this->appendItem(m_italic); + this->appendItem(m_underline); +} + +QWidget *FontPropItem::createProperyEditor(QWidget *parent) const +{ + return new FontEditor(parent); +} + +QString FontPropItem::displayValue() const +{ + return toString(propertyValue().value());//propertyValue().toString();//toString(propertyValue().value()); +} + +void FontPropItem::setPropertyEditorData(QWidget* propertyEditor, const QModelIndex &) const +{ + FontEditor *editor =qobject_cast(propertyEditor); + editor->setFontValue(propertyValue().value()); +} + +void FontPropItem::setModelData(QWidget* propertyEditor, QAbstractItemModel* model, const QModelIndex &index) +{ + model->setData(index,qobject_cast(propertyEditor)->fontValue()); + object()->setProperty(propertyName().toLatin1(),propertyValue()); +} + +void FontPropItem::setPropertyValue(QVariant value) +{ + ObjectPropItem::setPropertyValue(value); + m_bold->setPropertyValue(value.value().bold()); + m_italic->setPropertyValue(value.value().italic()); + m_underline->setPropertyValue(value.value().underline()); + m_pointSize->setPropertyValue(value.value().pointSize()); + m_family->setPropertyValue(value.value()); +} + +QString FontPropItem::toString(QFont value) const +{ + QString attribs=""; + if (value.bold()) (attribs=="") ? attribs+="b":attribs+=",b"; + if (value.italic()) (attribs=="") ? attribs+="i":attribs+=",i"; + if (attribs!="") attribs="["+attribs+"]"; + return "\""+ value.family()+"\" "+QString::number(value.pointSize())+" "+attribs; +} + +QString FontFamilyPropItem::displayValue() const +{ + QFont font = propertyValue().value(); + return font.family(); +} + +QWidget *FontFamilyPropItem::createProperyEditor(QWidget *parent) const +{ + QFontComboBox* editor = new QFontComboBox(parent); + editor->setFont(propertyValue().value()); + return editor; +} + +void FontFamilyPropItem::setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const +{ + QFontComboBox* editor = qobject_cast(propertyEditor); + editor->setCurrentFont(propertyValue().value()); +} + +void FontFamilyPropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index) +{ + QFont font = qobject_cast(propertyEditor)->currentFont(); + model->setData(index,font); + object()->setProperty(parent()->propertyName().toLatin1(),font); +} + +void FontAttribPropItem::setModelData(QWidget *propertyEditor , QAbstractItemModel *model, const QModelIndex &index) +{ + model->setData(index,qobject_cast(propertyEditor)->isChecked()); + QFont font = object()->property(parent()->propertyName().toLatin1()).value(); + if (propertyName()=="bold"){ + font.setBold(propertyValue().toBool()); + } + if (propertyName()=="italic"){ + font.setItalic(propertyValue().toBool()); + } + if (propertyName()=="underline"){ + font.setUnderline(propertyValue().toBool()); + } + object()->setProperty(parent()->propertyName().toLatin1(),font); +} + +void FontPointSizePropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index) +{ + model->setData(index,qobject_cast(propertyEditor)->value()); + QFont font = object()->property(parent()->propertyName().toLatin1()).value(); + font.setPointSize(propertyValue().toInt()); + object()->setProperty(parent()->propertyName().toLatin1(),font); +} + +} diff --git a/src/objectinspector/propertyItems/lrfontpropitem.h b/src/objectinspector/propertyItems/lrfontpropitem.h new file mode 100644 index 0000000..92c0405 --- /dev/null +++ b/src/objectinspector/propertyItems/lrfontpropitem.h @@ -0,0 +1,92 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRFONTPROPITEM_H +#define LRFONTPROPITEM_H +#include "lrobjectpropitem.h" +#include "lrboolpropitem.h" +#include "lrintpropitem.h" + +namespace LimeReport{ + +class FontFamilyPropItem : public ObjectPropItem +{ + Q_OBJECT +public: + FontFamilyPropItem():ObjectPropItem(){} + FontFamilyPropItem(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value,ObjectPropItem* parent, bool readonly=true) + :ObjectPropItem(object, objects, name, displayName, value, parent, readonly){} + QString displayValue() const; + QWidget* createProperyEditor(QWidget *parent) const; + void setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const; + void setModelData(QWidget *propertyEditor , QAbstractItemModel *model, const QModelIndex &index); +}; + +class FontPointSizePropItem : public IntPropItem +{ + Q_OBJECT +public: + FontPointSizePropItem():IntPropItem(){} + FontPointSizePropItem(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value,ObjectPropItem* parent, bool readonly=true) + :IntPropItem(object, objects, name, displayName, value, parent, readonly){} + void setModelData(QWidget *propertyEditor , QAbstractItemModel *model, const QModelIndex &index); +}; + +class FontAttribPropItem : public BoolPropItem +{ + Q_OBJECT +public: + FontAttribPropItem():BoolPropItem(){} + FontAttribPropItem(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value,ObjectPropItem* parent, bool readonly=true) + :BoolPropItem(object, objects, name, displayName, value, parent, readonly){} + void setModelData(QWidget *propertyEditor , QAbstractItemModel *model, const QModelIndex &index); +}; + +class FontPropItem : public ObjectPropItem +{ + Q_OBJECT +public: + FontPropItem():ObjectPropItem(){} + FontPropItem(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value,ObjectPropItem* parent, bool readonly); + QWidget* createProperyEditor(QWidget *parent) const; + QString displayValue() const; + void setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const; + void setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index); + void setPropertyValue(QVariant value); +protected: + QString toString(QFont value) const; + FontPointSizePropItem* m_pointSize; + FontAttribPropItem *m_bold; + FontAttribPropItem *m_italic; + FontAttribPropItem *m_underline; + FontFamilyPropItem *m_family; +}; + +} +#endif // LRFONTPROPITEM_H diff --git a/src/objectinspector/propertyItems/lrgroupfieldpropitem.cpp b/src/objectinspector/propertyItems/lrgroupfieldpropitem.cpp new file mode 100644 index 0000000..b7027c5 --- /dev/null +++ b/src/objectinspector/propertyItems/lrgroupfieldpropitem.cpp @@ -0,0 +1,76 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrgroupfieldpropitem.h" +#include "../editors/lrcomboboxeditor.h" +#include "lrgroupbands.h" +#include "lrreportengine_p.h" + +namespace { + LimeReport::ObjectPropItem* createFieldPropItem(QObject *object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly){ + return new LimeReport::GroupFieldPropItem(object, objects, name, displayName, data, parent, readonly); + } + bool registredGroupFieldProp = LimeReport::ObjectPropFactory::instance().registerCreator( + LimeReport::APropIdent("groupFieldName","LimeReport::GroupBandHeader"),QObject::tr("field"),createFieldPropItem + ); +} +namespace LimeReport { + +QWidget *GroupFieldPropItem::createProperyEditor(QWidget *parent) const +{ + ComboBoxEditor *editor = new ComboBoxEditor(parent); + editor->setEditable(true); + GroupBandHeader *item=dynamic_cast(object()); + if (item){ + DataBandDesignIntf* dataBand = dynamic_cast(item->parentBand()); + if (dataBand){ + int propertyIndex = dataBand->metaObject()->indexOfProperty("datasource"); + + if (item && propertyIndex>0){ + editor->addItems(item->reportEditor()->dataManager()->fieldNames(dataBand->property("datasource").toString())); + } + } + } + return editor; +} + +void GroupFieldPropItem::setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const +{ + ComboBoxEditor *editor=qobject_cast(propertyEditor); + editor->setTextValue(propertyValue().toString()); +} + +void GroupFieldPropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index) +{ + model->setData(index,qobject_cast(propertyEditor)->text()); + object()->setProperty(propertyName().toLatin1(),propertyValue()); +} + +} + diff --git a/src/objectinspector/propertyItems/lrgroupfieldpropitem.h b/src/objectinspector/propertyItems/lrgroupfieldpropitem.h new file mode 100644 index 0000000..3f72fff --- /dev/null +++ b/src/objectinspector/propertyItems/lrgroupfieldpropitem.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRGROUPFIELDPROPITEM_H +#define LRGROUPFIELDPROPITEM_H + +#include "lrobjectpropitem.h" +namespace LimeReport{ + +class GroupFieldPropItem : public ObjectPropItem +{ +public: + GroupFieldPropItem(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value,ObjectPropItem* parent, bool readonly) + :ObjectPropItem(object, objects, name, displayName, value, parent, readonly){} + QWidget* createProperyEditor(QWidget *parent) const; + void setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const; + void setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index); +}; + +} + + +#endif // LRGROUPFIELDPROPITEM_H diff --git a/src/objectinspector/propertyItems/lrimagepropitem.cpp b/src/objectinspector/propertyItems/lrimagepropitem.cpp new file mode 100644 index 0000000..753e18c --- /dev/null +++ b/src/objectinspector/propertyItems/lrimagepropitem.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrimagepropitem.h" +#include "editors/lrimageeditor.h" + +namespace{ + LimeReport::ObjectPropItem * createImagePropItem( + QObject *object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly) + { + return new LimeReport::ImagePropItem(object, objects, name, displayName, data, parent, readonly); + } + bool registredImageProp = LimeReport::ObjectPropFactory::instance().registerCreator(LimeReport::APropIdent("QImage",""),QObject::tr("QImage"),createImagePropItem); +} + +namespace LimeReport{ + +QWidget* ImagePropItem::createProperyEditor(QWidget *parent) const +{ + return new ImageEditor(parent); +} + +QString ImagePropItem::displayValue() const +{ + return (propertyValue().isNull())?"":"Picture"; +} + +void ImagePropItem::setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const +{ + ImageEditor *editor =qobject_cast(propertyEditor); + editor->setImage(propertyValue().value()); +} + +void ImagePropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index) +{ + model->setData(index,qobject_cast(propertyEditor)->image()); + object()->setProperty(propertyName().toLatin1(),propertyValue()); +} + +QIcon ImagePropItem::iconValue() const +{ + return QIcon(QPixmap::fromImage(propertyValue().value())); +} + +} diff --git a/src/objectinspector/propertyItems/lrimagepropitem.h b/src/objectinspector/propertyItems/lrimagepropitem.h new file mode 100644 index 0000000..e61c9b9 --- /dev/null +++ b/src/objectinspector/propertyItems/lrimagepropitem.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRIMAGEPROPITEM_H +#define LRIMAGEPROPITEM_H + +#include "lrobjectpropitem.h" +namespace LimeReport{ + +class ImagePropItem : public ObjectPropItem +{ + Q_OBJECT +public: + ImagePropItem():ObjectPropItem(){} + ImagePropItem(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value,ObjectPropItem* parent, bool readonly) + :ObjectPropItem(object, objects, name, displayName, value, parent, readonly){} + QWidget* createProperyEditor(QWidget *parent) const; + QString displayValue() const; + void setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const; + void setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index); + virtual QIcon iconValue() const; +}; + +} +#endif // LRIMAGEPROPITEM_H diff --git a/src/objectinspector/propertyItems/lrintpropitem.cpp b/src/objectinspector/propertyItems/lrintpropitem.cpp new file mode 100644 index 0000000..af1d580 --- /dev/null +++ b/src/objectinspector/propertyItems/lrintpropitem.cpp @@ -0,0 +1,65 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrintpropitem.h" +#include +#include + +namespace{ + LimeReport::ObjectPropItem * createIntPropItem( + QObject *object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly) + { + return new LimeReport::IntPropItem(object, objects, name, displayName, data, parent, readonly); + } + bool registred = LimeReport::ObjectPropFactory::instance().registerCreator(LimeReport::APropIdent("int",""),QObject::tr("int"),createIntPropItem); +} // namespace + +namespace LimeReport{ + +QWidget *IntPropItem::createProperyEditor(QWidget *parent) const +{ + QSpinBox *editor= new QSpinBox(parent); + editor->setMaximum(std::numeric_limits::max()); + editor->setMinimum(std::numeric_limits::min()); + return editor; +} + +void IntPropItem::setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const +{ + QSpinBox *editor =qobject_cast(propertyEditor); + editor->setValue(propertyValue().toInt()); +} + +void IntPropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index) +{ + model->setData(index,qobject_cast(propertyEditor)->value()); + object()->setProperty(propertyName().toLatin1(),propertyValue()); +} + +} // namespace LimeReport diff --git a/src/objectinspector/propertyItems/lrintpropitem.h b/src/objectinspector/propertyItems/lrintpropitem.h new file mode 100644 index 0000000..2373cab --- /dev/null +++ b/src/objectinspector/propertyItems/lrintpropitem.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRINTPROPITEM_H +#define LRINTPROPITEM_H + +#include "lrobjectpropitem.h" + +namespace LimeReport { +class IntPropItem : public ObjectPropItem +{ + Q_OBJECT +public: + IntPropItem():ObjectPropItem(){} + IntPropItem(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value, ObjectPropItem* parent, bool readonly) + :ObjectPropItem(object, objects, name, displayName, value, parent, readonly){} + QWidget* createProperyEditor(QWidget *parent) const; + void setPropertyEditorData(QWidget * propertyEditor, const QModelIndex &) const; + void setModelData(QWidget * propertyEditor, QAbstractItemModel * model, const QModelIndex & index); +}; + +} // namespace LimeReport + +#endif // LRINTPROPITEM_H diff --git a/src/objectinspector/propertyItems/lrqrealpropitem.cpp b/src/objectinspector/propertyItems/lrqrealpropitem.cpp new file mode 100644 index 0000000..e027163 --- /dev/null +++ b/src/objectinspector/propertyItems/lrqrealpropitem.cpp @@ -0,0 +1,67 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrqrealpropitem.h" + +#include +#include + +namespace{ + LimeReport::ObjectPropItem * createQRealPropItem( + QObject *object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly) + { + return new LimeReport::QRealPropItem(object, objects, name, displayName, data, parent, readonly); + } + bool registred = LimeReport::ObjectPropFactory::instance().registerCreator(LimeReport::APropIdent("qreal",""),QObject::tr("qreal"),createQRealPropItem); + bool registredDouble = LimeReport::ObjectPropFactory::instance().registerCreator(LimeReport::APropIdent("double",""),QObject::tr("qreal"),createQRealPropItem); +} + +namespace LimeReport{ + +QWidget *QRealPropItem::createProperyEditor(QWidget *parent) const +{ + QDoubleSpinBox *editor= new QDoubleSpinBox(parent); + editor->setMaximum(std::numeric_limits::max()); + editor->setMinimum(std::numeric_limits::max()*-1); + return editor; +} + +void QRealPropItem::setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const +{ + QDoubleSpinBox *editor =qobject_cast(propertyEditor); + editor->setValue(propertyValue().toDouble()); +} + +void QRealPropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index) +{ + model->setData(index,qobject_cast(propertyEditor)->value()); + object()->setProperty(propertyName().toLatin1(),propertyValue()); +} + +} diff --git a/src/objectinspector/propertyItems/lrqrealpropitem.h b/src/objectinspector/propertyItems/lrqrealpropitem.h new file mode 100644 index 0000000..d06872f --- /dev/null +++ b/src/objectinspector/propertyItems/lrqrealpropitem.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRQREALPROPITEM_H +#define LRQREALPROPITEM_H + +#include "lrobjectpropitem.h" + +namespace LimeReport { + +class QRealPropItem : public ObjectPropItem +{ + Q_OBJECT +public: + QRealPropItem():ObjectPropItem(){} + QRealPropItem(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value,ObjectPropItem* parent, bool readonly) + :ObjectPropItem(object, objects, name, displayName, value, parent, readonly){} + QWidget* createProperyEditor(QWidget *parent) const; + void setPropertyEditorData(QWidget * propertyEditor, const QModelIndex &) const; + void setModelData(QWidget * propertyEditor, QAbstractItemModel * model, const QModelIndex & index); +}; + +} + + +#endif // LRQREALPROPITEM_H diff --git a/src/objectinspector/propertyItems/lrrectproptem.cpp b/src/objectinspector/propertyItems/lrrectproptem.cpp new file mode 100644 index 0000000..5335c9a --- /dev/null +++ b/src/objectinspector/propertyItems/lrrectproptem.cpp @@ -0,0 +1,210 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrrectproptem.h" +#include "lrobjectpropitem.h" +#include "lrbanddesignintf.h" +#include "lrpageitemdesignintf.h" +#include "lrglobal.h" +#include "lrobjectitemmodel.h" + +#include +#include +#include +#include + +namespace{ + LimeReport::ObjectPropItem * createReqtItem( + QObject *object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly + ){ + return new LimeReport::RectPropItem(object, objects, name, displayName, data, parent, readonly); + } + LimeReport::ObjectPropItem * createReqtMMItem( + QObject*object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly + ){ + return new LimeReport::RectMMPropItem(object, objects, name, displayName, data, parent, readonly); + } + bool registredRectProp = LimeReport::ObjectPropFactory::instance().registerCreator(LimeReport::APropIdent("QRect",""),QObject::tr("QRect"),createReqtItem); + bool registredRectFProp = LimeReport::ObjectPropFactory::instance().registerCreator(LimeReport::APropIdent("QRectF",""),QObject::tr("QRectF"),createReqtItem); + bool registredRectMMProp = LimeReport::ObjectPropFactory::instance().registerCreator(LimeReport::APropIdent("geometry","LimeReport::BaseDesignIntf"),QObject::tr("geometry"),createReqtMMItem); +} + +namespace LimeReport{ + +QRectF modifyRect(QRectF rect, const QString& name, qreal itemValue){ + + if (name=="x"){qreal width=rect.width(); rect.setX(itemValue);rect.setWidth(width);} + if (name=="y"){qreal heigh=rect.height(); rect.setY(itemValue);rect.setHeight(heigh);} + if (name=="height"){rect.setHeight(itemValue);} + if (name=="width"){rect.setWidth(itemValue);} + + return rect; +} + +} + +LimeReport::RectPropItem::RectPropItem(QObject *object, ObjectsList* objects, const QString &name, const QString &displayName, const QVariant &value, ObjectPropItem *parent, bool readonly): + ObjectPropItem(object, objects, name, displayName, value,parent,readonly) +{ + QRect rect=value.toRect(); + this->appendItem(new ObjectPropItem(object, objects, "x","x", rect.x(),this)); + this->appendItem(new ObjectPropItem(object, objects, "y","x", rect.y(),this)); + this->appendItem(new ObjectPropItem(object, objects, "width",tr("width"), rect.width(),this)); + this->appendItem(new ObjectPropItem(object, objects, "heigh",tr("height"),rect.height(),this)); +} + +QString LimeReport::RectPropItem::displayValue() const +{ + switch(propertyValue().type()){ + case QVariant::Rect: + return rectToString(propertyValue().toRect()); + break; + case QVariant::RectF: + return rectToString(propertyValue().toRect()); + break; + default : + return ObjectPropItem::displayValue(); + + } +} +template QString LimeReport::RectPropItem::rectToString(T rect) const +{ + return QString("[%1,%2] %3x%4").arg(rect.x()).arg(rect.y()).arg(rect.height()).arg(rect.width()); +} + +LimeReport::RectMMPropItem::RectMMPropItem(QObject *object, ObjectsList* objects, const QString &name, const QString &displayName, const QVariant &value, ObjectPropItem *parent, bool /*readonly*/): + ObjectPropItem(object, objects, name, displayName, value,parent) +{ + QRectF rect=value.toRect(); + LimeReport::BandDesignIntf* band = dynamic_cast(object); + LimeReport::PageItemDesignIntf *page = dynamic_cast(object); + if(band){ + this->appendItem(new LimeReport::RectMMValuePropItem(object, objects, "x","x",rect.x()/10,this,true)); + this->appendItem(new LimeReport::RectMMValuePropItem(object, objects, "y","y",rect.y()/10,this,true)); + this->appendItem(new LimeReport::RectMMValuePropItem(object, objects, "width",tr("width"), rect.width()/10,this,true)); + this->appendItem(new LimeReport::RectMMValuePropItem(object, objects, "height",tr("height"), rect.height()/10,this,false)); + } else if(page){ + this->appendItem(new LimeReport::RectMMValuePropItem(object, 0, "x","x",rect.x()/10,this,true)); + this->appendItem(new LimeReport::RectMMValuePropItem(object, 0, "y","y",rect.y()/10,this,true)); + this->appendItem(new LimeReport::RectMMValuePropItem(object, 0,"width", tr("width"), rect.width()/10,this,false)); + this->appendItem(new LimeReport::RectMMValuePropItem(object, 0, "height", tr("height"), rect.height()/10,this,false)); + } else { + this->appendItem(new LimeReport::RectMMValuePropItem(object, objects, "x","x",rect.x()/10,this,false)); + this->appendItem(new LimeReport::RectMMValuePropItem(object, objects, "y","y",rect.y()/10,this,false)); + this->appendItem(new LimeReport::RectMMValuePropItem(object, objects, "width", tr("width"), rect.width()/10,this,false)); + this->appendItem(new LimeReport::RectMMValuePropItem(object, objects, "height", tr("height"), rect.height()/10,this,false)); + } + LimeReport::BaseDesignIntf * item = dynamic_cast(object); + if (item){ + connect(item,SIGNAL(geometryChanged(QObject*,QRectF,QRectF)),this,SLOT(itemGeometryChanged(QObject*,QRectF,QRectF))); + connect(item,SIGNAL(posChanged(QObject*,QPointF,QPointF)),this,SLOT(itemPosChanged(QObject*,QPointF,QPointF))); + } + +} +QString LimeReport::RectMMPropItem::displayValue() const +{ + QRectF rect = propertyValue().toRectF(); + return QString("[%1,%2] %3x%4 mm") + .arg(rect.x()/10,0,'f',2) + .arg(rect.y()/10,0,'f',2) + .arg(rect.height()/10,0,'f',2) + .arg(rect.width()/10,0,'f',2); +} + +LimeReport::RectMMValuePropItem::RectMMValuePropItem(QObject *object, ObjectsList* objects, const QString &name, const QString &displayName, const QVariant &value, ObjectPropItem *parent, bool readonly +):ObjectPropItem(object, objects, name, displayName, value,parent,readonly){} + +QWidget * LimeReport::RectMMValuePropItem::createProperyEditor(QWidget *parent) const +{ + QDoubleSpinBox *editor= new QDoubleSpinBox(parent); + editor->setMaximum(100000); + editor->setSuffix(" mm"); + return editor; +} + +void LimeReport::RectMMValuePropItem::setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const +{ + QDoubleSpinBox *editor = qobject_cast(propertyEditor); + editor->setValue(propertyValue().toDouble()); +} + +void LimeReport::RectMMValuePropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index) +{ + model->setData(index,qobject_cast(propertyEditor)->value()); + QRectF rect=object()->property(parent()->propertyName().toLatin1()).toRectF(); + object()->setProperty(parent()->propertyName().toLatin1(),modifyRect(rect,propertyName(),propertyValue().toReal()*10)); +} + +QString LimeReport::RectMMValuePropItem::displayValue() const +{ + return QString::number(propertyValue().toReal())+" "+QObject::tr("mm"); +} + +void LimeReport::RectMMPropItem::itemPosChanged(QObject* /*object*/, QPointF newPos, QPointF oldPos) +{ + if (newPos.x()!=oldPos.x()){ + setValue("x",newPos.x()); + } + if (newPos.y()!=oldPos.y()){ + setValue("y",newPos.y()); + } +} + +void LimeReport::RectMMPropItem::itemGeometryChanged(QObject * /*object*/, QRectF newGeometry, QRectF oldGeometry) +{ + if (newGeometry.x()!=oldGeometry.x()){ + setValue("x",newGeometry.x()); + } + if (newGeometry.y()!=oldGeometry.y()){ + setValue("y",newGeometry.y()); + } + if (newGeometry.width()!=oldGeometry.width()){ + setValue("width",newGeometry.width()); + } + if (newGeometry.height()!=oldGeometry.height()){ + setValue("height",newGeometry.height()); + } +} + +void LimeReport::RectMMPropItem::setValue(const QString &name, qreal value) +{ + if (name!=""){ + LimeReport::ObjectPropItem* propItem = findChild(name); + if (propItem) { + propItem->setPropertyValue(value/10); + setPropertyValue(LimeReport::modifyRect(propertyValue().toRectF(),name,value)); + LimeReport::QObjectPropertyModel *itemModel=dynamic_cast(model()); + if (itemModel) { + itemModel->itemDataChanged(modelIndex()); + if (propItem->modelIndex().isValid()) + itemModel->itemDataChanged(propItem->modelIndex()); + } + } + } +} diff --git a/src/objectinspector/propertyItems/lrrectproptem.h b/src/objectinspector/propertyItems/lrrectproptem.h new file mode 100644 index 0000000..b74ba75 --- /dev/null +++ b/src/objectinspector/propertyItems/lrrectproptem.h @@ -0,0 +1,72 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRRECTPROPTEM_H +#define LRRECTPROPTEM_H +#include "lrobjectpropitem.h" +#include +#include + +namespace LimeReport{ + +class RectPropItem : public ObjectPropItem{ + Q_OBJECT +public: + RectPropItem():ObjectPropItem(){} + RectPropItem(QObject *object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value, ObjectPropItem* parent, bool readonly=true); + QString displayValue() const; + template QString rectToString(T rect) const; +}; + +class RectMMPropItem : public ObjectPropItem{ + Q_OBJECT +public: + RectMMPropItem():ObjectPropItem(){} + RectMMPropItem(QObject *object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value, ObjectPropItem* parent, bool readonly=true); + QString displayValue() const; +public slots: + void itemPosChanged(QObject* /*object*/, QPointF newPos, QPointF oldPos); + void itemGeometryChanged(QObject* object, QRectF newGeometry, QRectF oldGeometry); +private: + void setValue(const QString& propertyName, qreal propertyValue); +}; + +class RectMMValuePropItem : public ObjectPropItem{ + Q_OBJECT +public: + RectMMValuePropItem():ObjectPropItem(){} + RectMMValuePropItem(QObject *object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value, ObjectPropItem* parent, bool readonly ); + QString displayValue() const; + QWidget* createProperyEditor(QWidget *) const; + void setPropertyEditorData(QWidget *, const QModelIndex &) const; + void setModelData(QWidget *, QAbstractItemModel *, const QModelIndex &); +}; + +} +#endif // LRRECTPROPTEM_H diff --git a/src/objectinspector/propertyItems/lrstringpropitem.cpp b/src/objectinspector/propertyItems/lrstringpropitem.cpp new file mode 100644 index 0000000..56445a9 --- /dev/null +++ b/src/objectinspector/propertyItems/lrstringpropitem.cpp @@ -0,0 +1,72 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include +#include +#include + +#include "lrstringpropitem.h" +#include "lrobjectpropitem.h" +#include "objectinspector/editors/lrbuttonlineeditor.h" + +namespace{ + LimeReport::ObjectPropItem * createStringPropItem( + QObject *object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly) + { + return new LimeReport::StringPropItem(object, objects, name, displayName, data, parent, readonly); + } + bool registredStringProp = LimeReport::ObjectPropFactory::instance().registerCreator(LimeReport::APropIdent("QString",""),QObject::tr("QString"),createStringPropItem); +} // namespace + +namespace LimeReport{ + + +QWidget * StringPropItem::createProperyEditor(QWidget *parent) const +{ + return new ButtonLineEditor(object()->objectName()+"."+displayName(),parent); +} + +void StringPropItem::setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const +{ + ButtonLineEditor *editor =qobject_cast(propertyEditor); + editor->setText(propertyValue().toString()); +} + +void StringPropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index) +{ + model->setData(index,qobject_cast(propertyEditor)->text()); + object()->setProperty(propertyName().toLatin1(),propertyValue()); +} + +QString StringPropItem::displayValue() const +{ + return propertyValue().toString().simplified(); +} + +} // namespace LimeReport diff --git a/src/objectinspector/propertyItems/lrstringpropitem.h b/src/objectinspector/propertyItems/lrstringpropitem.h new file mode 100644 index 0000000..091ef1c --- /dev/null +++ b/src/objectinspector/propertyItems/lrstringpropitem.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRSTRINGPROPITEM_H +#define LRSTRINGPROPITEM_H +#include "lrobjectpropitem.h" + +namespace LimeReport{ +class StringPropItem : public LimeReport::ObjectPropItem{ + Q_OBJECT +public: + StringPropItem():ObjectPropItem(){} + StringPropItem(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value, ObjectPropItem* parent, bool readonly) + :ObjectPropItem(object, objects, name, displayName, value, parent, readonly){} + QWidget* createProperyEditor(QWidget *parent) const; + QString displayValue() const; + void setPropertyEditorData(QWidget *, const QModelIndex &) const; + void setModelData(QWidget *, QAbstractItemModel *, const QModelIndex &); +}; +} // namespace LimeReport +#endif // LRSTRINGPROPITEM_H diff --git a/src/objectsbrowser/lrobjectbrowser.cpp b/src/objectsbrowser/lrobjectbrowser.cpp new file mode 100644 index 0000000..89329d3 --- /dev/null +++ b/src/objectsbrowser/lrobjectbrowser.cpp @@ -0,0 +1,279 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrobjectbrowser.h" +#include "lritemdesignintf.h" +#include "lrbanddesignintf.h" +#include + +namespace LimeReport{ + + +ObjectBrowser::ObjectBrowser(QWidget *parent) + :QWidget(parent), m_changingItemSelection(false) +{ + QVBoxLayout *layout = new QVBoxLayout(this); + setLayout(layout); + layout->setMargin(2); + m_treeView = new QTreeWidget(this); + layout->addWidget(m_treeView); + m_treeView->headerItem()->setText(0,tr("Objects")); + m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelection); +} + +void ObjectBrowser::setReportEditor(ReportDesignWidget *report) +{ + m_report=report; + connect(m_report,SIGNAL(cleared()),this,SLOT(slotClear())); + connect(m_report, SIGNAL(loaded()), this, SLOT(slotReportLoaded())); + connect(m_report, SIGNAL(activePageChanged()), this, SLOT(slotActivePageChanged())); + + connect(m_report,SIGNAL(itemAdded(LimeReport::PageDesignIntf*,LimeReport::BaseDesignIntf*)), + this, SLOT(slotItemAdded(LimeReport::PageDesignIntf*,LimeReport::BaseDesignIntf*))); + connect(m_report, SIGNAL(itemDeleted(LimeReport::PageDesignIntf*,LimeReport::BaseDesignIntf*)), + this, SLOT(slotItemDeleted(LimeReport::PageDesignIntf*,LimeReport::BaseDesignIntf*))); + + connect(m_report, SIGNAL(bandAdded(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*)), + this, SLOT(slotBandAdded(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*))); + connect(m_report, SIGNAL(bandDeleted(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*)), + this, SLOT(slotBandDeleted(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*))); + connect(m_treeView, SIGNAL(itemSelectionChanged()), + this, SLOT(slotObjectTreeItemSelectionChanged()) ); + connect(m_report, SIGNAL(itemSelected(LimeReport::BaseDesignIntf*)), + this, SLOT(slotItemSelected(LimeReport::BaseDesignIntf*))); + + connect(m_report, SIGNAL(multiItemSelected()), + this, SLOT(slotMultiItemSelected()) ); + + buildTree(); +} + +void ObjectBrowser::setMainWindow(QMainWindow *mainWindow) +{ + m_mainWindow=mainWindow; +} + +void ObjectBrowser::slotClear() +{ + +} + +void ObjectBrowser::fillNode(QTreeWidgetItem* parentNode, BaseDesignIntf* reportItem, BaseDesignIntf *ignoredItem){ + foreach (BaseDesignIntf* item, reportItem->childBaseItems()) { + if (item != ignoredItem){ + ObjectBrowserNode* treeItem = new ObjectBrowserNode(parentNode); + treeItem->setText(0,item->objectName()); + treeItem->setObject(item); + treeItem->setIcon(0,QIcon(":/items/"+extractClassName(item->metaObject()->className()))); + connect(item, SIGNAL(propertyObjectNameChanged(QString,QString)), + this, SLOT(slotPropertyObjectNameChanged(QString,QString))); + m_itemsMap.insert(item,treeItem); + parentNode->addChild(treeItem); + if (!item->childBaseItems().isEmpty()) + fillNode(treeItem,item, ignoredItem); + } + } +} + +void ObjectBrowser::buildTree(BaseDesignIntf* ignoredItem){ + + m_treeView->clear(); + m_itemsMap.clear(); + + ObjectBrowserNode *topLevelItem=new ObjectBrowserNode(m_treeView); + topLevelItem->setText(0,m_report->activePage()->objectName()); + topLevelItem->setObject(m_report->activePage()); + m_itemsMap.insert(m_report->activePage(),topLevelItem); + + m_treeView->addTopLevelItem(topLevelItem); + foreach (QGraphicsItem* item, m_report->activePage()->items()) { + if (item != ignoredItem){ + BaseDesignIntf* reportItem = dynamic_cast(item); + if (reportItem && reportItem->parentItem()==0){ + ObjectBrowserNode* tItem = new ObjectBrowserNode(topLevelItem); + tItem->setText(0,reportItem->objectName()); + tItem->setObject(reportItem); + tItem->setIcon(0,QIcon(":/items/"+extractClassName(reportItem->metaObject()->className()))); + connect(reportItem, SIGNAL(propertyObjectNameChanged(QString,QString)), + this, SLOT(slotPropertyObjectNameChanged(QString,QString))); + m_itemsMap.insert(reportItem,tItem); + fillNode(tItem,reportItem, ignoredItem); + topLevelItem->addChild(tItem); + } + } + } + m_treeView->sortItems(0,Qt::AscendingOrder); + m_treeView->expandAll(); +} + +void ObjectBrowser::findAndRemove(QTreeWidgetItem* node, BaseDesignIntf* item){ + + for (int i=0;ichildCount();i++){ + QTreeWidgetItem* treeItem = node->child(i); + if (treeItem->text(0)==item->objectName()){ + node->removeChild(treeItem); + break; + } else { + if (treeItem->childCount()>0) findAndRemove(treeItem, item); + } + } + +} + +void ObjectBrowser::slotPropertyObjectNameChanged(const QString &oldName, const QString &newName) +{ + Q_UNUSED(oldName) + if (m_itemsMap.contains(sender())){ + m_itemsMap.value(sender())->setText(0,newName); + } +} + +//void ObjectBrowser::slotObjectNameChanged(const QString &objectName) +//{ +// if (m_itemsMap.contains(sender())){ +// m_itemsMap.value(sender())->setText(0,objectName); +// } +//} + +void ObjectBrowser::removeItem(BaseDesignIntf *item) +{ + findAndRemove(m_treeView->topLevelItem(0),item); +} + +void ObjectBrowser::slotReportLoaded() +{ + buildTree(); +} + +void ObjectBrowser::slotActivePageChanged() +{ + buildTree(); +} + +void ObjectBrowser::slotBandAdded(LimeReport::PageDesignIntf *, BandDesignIntf *) +{ + buildTree(); +} + +void ObjectBrowser::slotBandDeleted(PageDesignIntf *, BandDesignIntf * item) +{ + buildTree(item); +} + +void ObjectBrowser::slotItemAdded(PageDesignIntf *, BaseDesignIntf *) +{ + buildTree(); +} + +void ObjectBrowser::slotItemDeleted(PageDesignIntf *, BaseDesignIntf *item) +{ + if (dynamic_cast(item)){ + buildTree(item); + } else { + removeItem(item); + } +} + +void ObjectBrowser::slotObjectTreeItemSelectionChanged() +{ + if (!m_changingItemSelection){ + m_changingItemSelection = true; + m_report->activePage()->clearSelection(); + foreach(QTreeWidgetItem* item, m_treeView->selectedItems()){ + ObjectBrowserNode* tn = dynamic_cast(item); + if (tn){ + + BaseDesignIntf* si = dynamic_cast(tn->object()); + if (si) { + m_report->activePage()->animateItem(si); + si->setSelected(true); + } + } + } + m_changingItemSelection = false; + } +} + +void ObjectBrowser::slotItemSelected(LimeReport::BaseDesignIntf *item) +{ + if (!m_changingItemSelection){ + m_changingItemSelection = true; + + m_treeView->selectionModel()->clear(); + BaseDesignIntf* bg = dynamic_cast(item); + if (bg){ + if (m_itemsMap.value(bg)) + m_itemsMap.value(bg)->setSelected(true); + } + + m_changingItemSelection = false; + } +} + +void ObjectBrowser::slotMultiItemSelected() +{ + m_changingItemSelection = true; + + m_treeView->selectionModel()->clear(); + + foreach(QGraphicsItem* item, m_report->activePage()->selectedItems()){ + BaseDesignIntf* bg = dynamic_cast(item); + if (bg){ + m_itemsMap.value(bg)->setSelected(true); + } + } + + m_changingItemSelection = false; +} + +void ObjectBrowserNode::setObject(QObject *value) +{ + m_object = value; +} + +QObject *ObjectBrowserNode::object() const +{ + return m_object; +} + +ObjectBrowserNode::ObjectBrowserNode(QTreeWidget *view) + :QTreeWidgetItem(view), m_object(0){} + +ObjectBrowserNode::ObjectBrowserNode(QTreeWidgetItem *parent) + :QTreeWidgetItem(parent), m_object(0){} + +bool ObjectBrowserNode::operator <(const QTreeWidgetItem &other) const +{ + BandDesignIntf* band1 = dynamic_cast(m_object); + BandDesignIntf* band2 = dynamic_cast(dynamic_cast(other).object()); + if (band1 && band2) return band1->bandIndex()bandIndex(); + return false; +} + +} //namespace LimeReport diff --git a/src/objectsbrowser/lrobjectbrowser.h b/src/objectsbrowser/lrobjectbrowser.h new file mode 100644 index 0000000..67ca58c --- /dev/null +++ b/src/objectsbrowser/lrobjectbrowser.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LROBJECTBROWSER_H +#define LROBJECTBROWSER_H + +#include +#include +#include "lrreportdesignwidget.h" +#include "lrbasedesignintf.h" + +namespace LimeReport{ + +class ObjectBrowserNode :public QTreeWidgetItem{ +public: + void setObject(QObject* value); + QObject* object() const; + explicit ObjectBrowserNode(QTreeWidget *view); + explicit ObjectBrowserNode(QTreeWidgetItem *parent); + bool operator <(const QTreeWidgetItem& other) const; +private: + QObject* m_object; +}; + +class ObjectBrowser :public QWidget +{ + Q_OBJECT +public: + ObjectBrowser(QWidget *parent=0); + void setReportEditor(LimeReport::ReportDesignWidget* report); + void setMainWindow(QMainWindow* mainWindow); +protected: + void fillNode(QTreeWidgetItem *parentNode, BaseDesignIntf *reportItem, BaseDesignIntf* ignoredItem = 0); + void buildTree(BaseDesignIntf *ignoredItem = 0); + void removeItem(BaseDesignIntf* item); + void findAndRemove(QTreeWidgetItem *node, BaseDesignIntf *item); +private slots: +// void slotObjectNameChanged(const QString& objectName); + void slotPropertyObjectNameChanged(const QString& oldName, const QString& newName); + void slotClear(); + void slotReportLoaded(); + void slotActivePageChanged(); + void slotBandAdded(LimeReport::PageDesignIntf*, LimeReport::BandDesignIntf*); + void slotBandDeleted(LimeReport::PageDesignIntf*, LimeReport::BandDesignIntf*item); + void slotItemAdded(LimeReport::PageDesignIntf*, LimeReport::BaseDesignIntf*); + void slotItemDeleted(LimeReport::PageDesignIntf*, LimeReport::BaseDesignIntf*item); + void slotObjectTreeItemSelectionChanged(); + void slotItemSelected(LimeReport::BaseDesignIntf* item); + void slotMultiItemSelected(); +private: + ReportDesignWidget* m_report; + QMainWindow* m_mainWindow; + QTreeWidget* m_treeView; + QMap m_itemsMap; + bool m_changingItemSelection; +}; + +} //namespace LimeReport +#endif // LROBJECTBROWSER_H diff --git a/src/report.qrc b/src/report.qrc new file mode 100644 index 0000000..8e711c0 --- /dev/null +++ b/src/report.qrc @@ -0,0 +1,158 @@ + + + images/pin_green.png + images/addBand.png + images/Control-Edit Box.png + images/disk_blue.png + images/folder.png + images/delete.png + images/document_add.png + images/document_zoom_in.png + images/document_zoom_out.png + images/prin-preview2.png + images/dialog-close.png + images/go-next.png + images/print2_big.png + images/next.png + images/prior.png + images/dialog-close_red.png + images/Hourglass_80.png + images/closebox.png + images/design.png + images/barcode.png + images/barcode2.png + images/edit_pecil2.png + images/undo1.png + images/redo1.png + images/copy24.png + images/edit-copy_1_24.png + images/edit-paste_1_24.png + images/cut24.png + images/save_as_1_24.png + images/move_top_1.png + images/move_back.png + images/bringToFront.png + images/sendToBack.png + images/to_left.png + images/to_right.png + images/to_center.png + images/to_same_width.png + images/to_same_height.png + images/to_top.png + images/cut_24.png + images/paste_1_24.png + images/to_bottom.png + images/to_h_center.png + images/folder1.png + images/document_add_1.png + images/zoom-in_2_16.png + images/document_zoom_in_1.png + images/document_zoom_out_1.png + images/prin-preview_4_24.png + images/print_2_24.png + images/hlayout.png + images/vlayout.png + images/edit_layout.png + images/layuot_move.png + images/hlayuot_1_24.png + images/layuot_select.png + images/layuot_create.png + images/layuot_create_24.png + images/layuot_select_24.png + images/layuot_delete_24.png + images/hlayuot_2_24.png + images/edit_layout_2_24.png + images/edit_control_24.png + images/edit_control_2_24.png + images/edit_layout_3_24.png + images/text_align_center.png + images/text-align-justify.png + images/text_align_left.png + images/text_align_right.png + images/text_bold.png + images/text_italic.png + images/text_underline.png + images/text-align-botom.png + images/text-align-top.png + images/text-align-v-center.png + images/allLines.png + images/bottomLine.png + images/leftLine.png + images/noLines.png + images/rightLine.png + images/topLine.png + images/new_leaf.png + images/save.png + images/copy.png + images/paste.png + images/cut.png + images/cut1.png + images/redo.png + images/undo.png + images/zoom_in.png + images/zoom_out.png + images/print.png + images/print_preview1.png + images/print_preview.png + images/print_preview2.png + images/allLines1.png + images/noLines1.png + images/leftLine1.png + images/bottomLine1.png + images/rightLine1.png + images/topLine1.png + images/toBack.png + images/toFront.png + images/toBottom.png + images/toCenter.png + images/toLeft1.png + images/toRight.png + images/toSameHeight.png + images/toSameWidth.png + images/toTop.png + images/toVCernter.png + images/text-align-botom1.png + images/text_align_center1.png + images/text-align-justify1.png + images/text_align_left1.png + images/text_align_right1.png + images/text-align-top1.png + images/text-align-v-center1.png + images/text_bold1.png + images/text_italic1.png + images/text_underline1.png + images/edit_control_3_24.png + images/edit_layout_4_24.png + images/hlayuot_3_24.png + images/addBand1.png + images/delete1.png + images/copy2.png + images/new_leaf1.png + images/paste1.png + images/zoom_in1.png + images/zoom_out1.png + images/folder3.png + images/dasabases.png + images/database.png + images/edit.png + images/table1.png + images/value.png + images/field.png + images/function2.png + images/function3.png + images/var1.png + images/variable.png + images/variable1.png + images/next1.png + images/prior1.png + images/next2.png + images/prior2.png + images/errors.png + images/main.png + images/first2.png + images/last2.png + images/logo.png + images/cpyright_logo.png + images/logo_100.png + + diff --git a/src/serializators/aserializatorintf.cpp b/src/serializators/aserializatorintf.cpp new file mode 100644 index 0000000..91eb6c9 --- /dev/null +++ b/src/serializators/aserializatorintf.cpp @@ -0,0 +1,30 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrserializatorintf.h" diff --git a/src/serializators/astorageintf.cpp b/src/serializators/astorageintf.cpp new file mode 100644 index 0000000..5812cf1 --- /dev/null +++ b/src/serializators/astorageintf.cpp @@ -0,0 +1,31 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "astorageintf.h" + diff --git a/src/serializators/lrserializatorintf.h b/src/serializators/lrserializatorintf.h new file mode 100644 index 0000000..ce6a44b --- /dev/null +++ b/src/serializators/lrserializatorintf.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRSERIALIZATORINTF_H +#define LRSERIALIZATORINTF_H +#include +namespace LimeReport { + +class SerializatorIntf +{ +public: + virtual QVariant loadValue()=0; + virtual void save(const QVariant& value,QString name)=0; + virtual ~SerializatorIntf(){} +}; + +} +#endif // LRSERIALIZATORINTF_H diff --git a/src/serializators/lrstorageintf.h b/src/serializators/lrstorageintf.h new file mode 100644 index 0000000..c53982c --- /dev/null +++ b/src/serializators/lrstorageintf.h @@ -0,0 +1,72 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRSTORAGEINTF_H +#define LRSTORAGEINTF_H + +#include + +class QString; +class QObject; + +namespace LimeReport{ + +class ObjectLoadingStateIntf{ +public: + virtual bool isLoading()=0; + virtual void objectLoadStarted()=0; + virtual void objectLoadFinished()=0; +}; + +class ItemsWriterIntf +{ +public: + virtual void putItem(QObject* item)=0; + virtual bool saveToFile(QString fileName) = 0; + virtual QString saveToString() = 0; + virtual ~ItemsWriterIntf(){} +}; + +class ItemsReaderIntf +{ +public: + typedef QSharedPointer Ptr; + virtual bool first()=0; + virtual bool next()=0; + virtual bool prior()=0; + virtual QString itemType()=0; + virtual QString itemClassName()=0; + virtual bool readItem(QObject *item)=0; + virtual int firstLevelItemsCount()=0; + virtual QString lastError()=0; + virtual ~ItemsReaderIntf(){} +}; + +} +#endif // LRSTORAGEINTF_H diff --git a/src/serializators/lrxmlbasetypesserializators.cpp b/src/serializators/lrxmlbasetypesserializators.cpp new file mode 100644 index 0000000..fcd2edf --- /dev/null +++ b/src/serializators/lrxmlbasetypesserializators.cpp @@ -0,0 +1,281 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrxmlbasetypesserializators.h" +#include "serializators/lrxmlserializatorsfactory.h" +#include "lrsimplecrypt.h" +#include +#include +#include + +namespace{ + +LimeReport::SerializatorIntf * createIntSerializator(QDomDocument *doc, QDomElement *node){ + return new LimeReport::XmlIntSerializator(doc,node); +} + +LimeReport::SerializatorIntf * createQRealSerializator(QDomDocument *doc, QDomElement *node){ + return new LimeReport::XmlQRealSerializator(doc,node); +} + +LimeReport::SerializatorIntf * createQStringSerializator(QDomDocument *doc, QDomElement *node){ + return new LimeReport::XmlQStringSerializator(doc,node); +} + +LimeReport::SerializatorIntf * createEnumAndFlagsSerializator(QDomDocument *doc, QDomElement *node){ + return new LimeReport::XmlEnumAndFlagsSerializator(doc,node); +} + +LimeReport::SerializatorIntf * createBoolSerializator(QDomDocument *doc, QDomElement *node){ + return new LimeReport::XmlBoolSerializator(doc,node); +} + +LimeReport::SerializatorIntf * createFontSerializator(QDomDocument *doc, QDomElement *node){ + return new LimeReport::XmlFontSerializator(doc,node); +} + +LimeReport::SerializatorIntf * createQSizeFSerializator(QDomDocument *doc, QDomElement *node){ + return new LimeReport::XmlQSizeFSerializator(doc,node); +} + +LimeReport::SerializatorIntf * createQImageSerializator(QDomDocument *doc, QDomElement *node){ + return new LimeReport::XmlQImageSerializator(doc,node); +} + +LimeReport::SerializatorIntf * createQColorSerializator(QDomDocument *doc, QDomElement *node){ + return new LimeReport::XmlColorSerializator(doc,node); +} + +LimeReport::SerializatorIntf* createQByteArraySerializator(QDomDocument *doc, QDomElement *node){ + return new LimeReport::XmlQByteArraySerializator(doc,node); +} + +bool registredQString = LimeReport::XMLAbstractSerializatorFactory::instance().registerCreator("QString", createQStringSerializator); +bool registredInt = LimeReport::XMLAbstractSerializatorFactory::instance().registerCreator("int", createIntSerializator); +bool registredEnumAndFlags = LimeReport::XMLAbstractSerializatorFactory::instance().registerCreator("enumAndFlags",createEnumAndFlagsSerializator); +bool registredBool = LimeReport::XMLAbstractSerializatorFactory::instance().registerCreator("bool", createBoolSerializator); +bool registredQFont = LimeReport::XMLAbstractSerializatorFactory::instance().registerCreator("QFont", createFontSerializator); +bool registredQSizeF = LimeReport::XMLAbstractSerializatorFactory::instance().registerCreator("QSizeF", createQSizeFSerializator); +bool registredQImage = LimeReport::XMLAbstractSerializatorFactory::instance().registerCreator("QImage", createQImageSerializator); +bool registredQReal = LimeReport::XMLAbstractSerializatorFactory::instance().registerCreator("qreal", createQRealSerializator); +bool registerDouble = LimeReport::XMLAbstractSerializatorFactory::instance().registerCreator("double", createQRealSerializator); +bool registerQColor = LimeReport::XMLAbstractSerializatorFactory::instance().registerCreator("QColor", createQColorSerializator); +bool registerQByteArray = LimeReport::XMLAbstractSerializatorFactory::instance().registerCreator("QByteArray", createQByteArraySerializator); + +} + + +namespace LimeReport{ + +void XmlBaseSerializator::saveBool(QDomElement node,QString name, bool value) +{ + if (value) node.setAttribute(name,1); + else node.setAttribute(name,0); +} + +void XmlQStringSerializator::save(const QVariant &value, QString name) +{ + QDomElement _node = doc()->createElement(name); + _node.setAttribute("Type","QString"); + if (name.compare("password")==0){ + Chipper chipper; + QByteArray ba = chipper.cryptString(value.toString()); + //ba.append(); + _node.setAttribute("Value",QString(ba.toBase64())); + } else { + _node.appendChild(doc()->createTextNode(value.toString())); + } + node()->appendChild(_node); +} + +QVariant XmlQStringSerializator::loadValue() +{ + if (node()->tagName().compare("password")==0){ + QByteArray ba; + Chipper chipper; + ba.append(node()->attribute("Value").toLatin1()); + return chipper.decryptByteArray(QByteArray::fromBase64(ba)); + } else + return node()->text(); +} + +void XmlIntSerializator::save(const QVariant &value, QString name) +{ + QDomElement _node = doc()->createElement(name); + _node.setAttribute("Type","int"); + _node.setAttribute("Value",value.toInt()); + node()->appendChild(_node); +} + +QVariant XmlIntSerializator::loadValue() +{ + return node()->attribute("Value").toInt(); +} + +void XmlEnumAndFlagsSerializator::save(const QVariant &value, QString name) +{ + QDomElement _node = doc()->createElement(name); + _node.setAttribute("Type","enumAndFlags"); + _node.setAttribute("Value",value.toInt()); + node()->appendChild(_node); +} + +QVariant XmlEnumAndFlagsSerializator::loadValue() +{ + return node()->attribute("Value").toInt(); +} + +void XmlBoolSerializator::save(const QVariant &value, QString name) +{ + QDomElement _node = doc()->createElement(name); + _node.setAttribute("Type","bool"); + if (value.toBool()) + _node.setAttribute("Value",1); + else _node.setAttribute("Value",0); + + node()->appendChild(_node); +} + +QVariant XmlBoolSerializator::loadValue() +{ + return node()->attribute("Value").toInt(); +} + +void XmlFontSerializator::save(const QVariant &value, QString name) +{ + + QFont font = value.value(); + QDomElement _node = doc()->createElement(name); + _node.setAttribute("Type","QFont"); + _node.setAttribute("family",font.family()); + _node.setAttribute("pointSize",font.pointSize()); + saveBool(_node,"bold",font.bold()); + saveBool(_node,"italic",font.italic()); + saveBool(_node,"undeline",font.underline()); + + node()->appendChild(_node); +} + +QVariant XmlFontSerializator::loadValue() +{ + QFont font; + + font.setFamily(node()->attribute("family")); + font.setPointSize(node()->attribute("pointSize").toInt()); + font.setBold(node()->attribute("bold").toInt()); + font.setItalic(node()->attribute("italic").toInt()); + font.setUnderline(node()->attribute("underline").toInt()); + return font; +} + +void XmlQSizeFSerializator::save(const QVariant &value, QString name) +{ + QSizeF size = value.toSizeF(); + QDomElement _node = doc()->createElement(name); + _node.setAttribute("Type","QSizeF"); + _node.setAttribute("width",QString::number(size.width())); + _node.setAttribute("height",QString::number(size.height())); + node()->appendChild(_node); +} + +QVariant XmlQSizeFSerializator::loadValue() +{ + QSizeF size; + size.setWidth(node()->attribute("width").toDouble()); + size.setHeight(node()->attribute("height").toDouble()); + return size; +} + +void XmlQImageSerializator::save(const QVariant &value, QString name) +{ + QImage image=value.value(); + QByteArray ba; + QBuffer buff(&ba); + buff.open(QIODevice::WriteOnly); + image.save(&buff,"PNG"); + QDomElement _node = doc()->createElement(name); + _node.setAttribute("Type","QImage"); + _node.appendChild(doc()->createTextNode(ba.toHex())); + node()->appendChild(_node); +} + +QVariant XmlQImageSerializator::loadValue() +{ + QImage img; + img.loadFromData(QByteArray::fromHex(node()->text().toLatin1()),"PNG"); + return img; +} + +void XmlQRealSerializator::save(const QVariant &value, QString name) +{ + QDomElement _node = doc()->createElement(name); + _node.setAttribute("Type","qreal"); + _node.setAttribute("Value",QString::number(value.toDouble())); + node()->appendChild(_node); +} + +QVariant XmlQRealSerializator::loadValue() +{ + return node()->attribute("Value").toDouble(); +} + +void XmlColorSerializator::save(const QVariant &value, QString name) +{ + QDomElement _node = doc()->createElement(name); + _node.setAttribute("Type","QColor"); + _node.setAttribute("Value",value.value().name()); + node()->appendChild(_node); +} + +QVariant XmlColorSerializator::loadValue() +{ + return QColor(node()->attribute("Value")); +} + +void XmlQByteArraySerializator::save(const QVariant &value, QString name) +{ + QDomElement _node = doc()->createElement(name); + _node.setAttribute("Type","QByteArray"); + _node.setAttribute("Value",QString(value.toByteArray().toBase64())); + node()->appendChild(_node); +} + +QVariant XmlQByteArraySerializator::loadValue() +{ + QByteArray ba; + ba.append(node()->attribute("Value").toLatin1()); + return QByteArray::fromBase64(ba); +} + + + +} + + + diff --git a/src/serializators/lrxmlbasetypesserializators.h b/src/serializators/lrxmlbasetypesserializators.h new file mode 100644 index 0000000..18dfb81 --- /dev/null +++ b/src/serializators/lrxmlbasetypesserializators.h @@ -0,0 +1,141 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRXMLBASETYPESSERIALIZATORS_H +#define LRXMLBASETYPESSERIALIZATORS_H + +#include "lrserializatorintf.h" +#include +#include + +namespace LimeReport{ + +class XmlBaseSerializator : public SerializatorIntf{ +public: + XmlBaseSerializator(QDomDocument *doc, QDomElement *node):m_doc(doc),m_node(node){} +protected: + QDomDocument* doc() {return m_doc;} + QDomElement* node() {if (!m_node) qDebug()<. * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrxmlqrectserializator.h" +#include "lrserializatorintf.h" +#include "lrxmlserializatorsfactory.h" + +#include +#include + +namespace{ + +LimeReport::SerializatorIntf * createQRectSerializator(QDomDocument *doc, QDomElement *node){ + return new LimeReport::XMLQRectSerializator(doc,node); +} + +LimeReport::SerializatorIntf * createQRectFSerializator(QDomDocument *doc, QDomElement *node){ + return new LimeReport::XMLQRectFSerializator(doc,node); +} + +bool registredQRect = LimeReport::XMLAbstractSerializatorFactory::instance().registerCreator("QRect", createQRectSerializator); +bool registredQRectF = LimeReport::XMLAbstractSerializatorFactory::instance().registerCreator("QRectF", createQRectSerializator); + +} + +QVariant LimeReport::XMLQRectSerializator::loadValue() +{ + QRect rect; + //QDomElement geometryNode = m_node->firstChildElement(name); + //if (!geometryNode.isNull()){ + rect = QRect( + m_node->attribute("x").toInt(), + m_node->attribute("y").toInt(), + m_node->attribute("width").toInt(), + m_node->attribute("height").toInt() + ); + //} + return rect; +} + +void LimeReport::XMLQRectSerializator::save(const QVariant &value, QString name) +{ + QDomElement geometryNode = m_doc->createElement(name); + geometryNode.setAttribute("Type","QRect"); + geometryNode.setAttribute("x",value.toRect().x()); + geometryNode.setAttribute("x",value.toRect().x()); + geometryNode.setAttribute("y",value.toRect().y()); + geometryNode.setAttribute("width",value.toRect().width()); + geometryNode.setAttribute("height",value.toRect().height()); + m_node->appendChild(geometryNode); +} + +void LimeReport::XMLQRectFSerializator::save(const QVariant &value, QString name) +{ + QDomElement geometryNode = m_doc->createElement(name); + geometryNode.setAttribute("Type","QRectF"); + geometryNode.setAttribute("x",value.toRect().x()); + geometryNode.setAttribute("y",value.toRect().y()); + geometryNode.setAttribute("width",value.toRect().width()); + geometryNode.setAttribute("height",value.toRect().height()); + m_node->appendChild(geometryNode); +} + +QVariant LimeReport::XMLQRectFSerializator::loadValue() +{ + QRectF rect; + //QDomElement geometryNode = m_node->firstChildElement(name); + //if (!geometryNode.isNull()){ + rect = QRect( + m_node->attribute("x").toDouble(), + m_node->attribute("y").toDouble(), + m_node->attribute("width").toDouble(), + m_node->attribute("height").toDouble() + ); + + //} + return rect; +} diff --git a/src/serializators/lrxmlqrectserializator.h b/src/serializators/lrxmlqrectserializator.h new file mode 100644 index 0000000..cc26275 --- /dev/null +++ b/src/serializators/lrxmlqrectserializator.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRXMLQRECTSERIALIZATOR_H +#define LRXMLQRECTSERIALIZATOR_H + +#include "lrserializatorintf.h" +#include + +namespace LimeReport{ + +class XMLQRectSerializator : public SerializatorIntf +{ +public: + XMLQRectSerializator(QDomDocument *doc, QDomElement *node):m_doc(doc),m_node(node){} + virtual void save(const QVariant &value,QString name); + virtual QVariant loadValue(); +private: + QDomDocument *m_doc; + QDomElement *m_node; +}; + +class XMLQRectFSerializator : public SerializatorIntf +{ +public: + XMLQRectFSerializator(QDomDocument *doc, QDomElement *node):m_doc(doc),m_node(node){} + virtual void save(const QVariant &value, QString name); + virtual QVariant loadValue(); +private: + QDomDocument *m_doc; + QDomElement *m_node; +}; + +} +#endif // LRXMLQRECTSERIALIZATOR_H diff --git a/src/serializators/lrxmlreader.cpp b/src/serializators/lrxmlreader.cpp new file mode 100644 index 0000000..4f2f282 --- /dev/null +++ b/src/serializators/lrxmlreader.cpp @@ -0,0 +1,228 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "stdexcept" + +#include "lrxmlreader.h" +#include "lrbasedesignintf.h" +#include "lrdesignelementsfactory.h" +#include "lrcollection.h" + +#include + +namespace LimeReport{ + +XMLReader::XMLReader() + : m_doc(new QDomDocument){} +XMLReader::XMLReader(QSharedPointer doc) + : m_doc(doc){} + +bool XMLReader::prepareReader(QDomDocument* doc) +{ + Q_UNUSED(doc); + m_error=QLatin1String("Context not initialized"); + return false; +} + +int XMLReader::firstLevelItemsCount() +{ + if (m_firstNode.childNodes().count()==0) return 0; + QDomElement tmpNode = m_firstNode; + int res=0; + while (!tmpNode.isNull()){ + res++; + tmpNode=tmpNode.nextSiblingElement(); + } + return res; +} + +bool XMLReader::first() +{ + if (extractFirstNode()){ + m_curNode = m_firstNode; + return !m_curNode.isNull(); + } + return false; +} + +bool XMLReader::next() +{ + m_curNode = m_curNode.nextSiblingElement(); + return !m_curNode.isNull(); +} + +bool XMLReader::prior() +{ + m_curNode = m_curNode.previousSiblingElement(); + return !m_curNode.isNull(); +} + +QString XMLReader::itemType() +{ + return m_curNode.attribute("Type"); +} + +QString XMLReader::itemClassName() +{ + return m_curNode.attribute("ClassName"); +} + +bool XMLReader::readItem(QObject *item) +{ + if (!m_curNode.isNull()){ + readItemFromNode(item,&m_curNode); + } else { + m_error=QString("Object %1 not founded").arg(item->objectName()); + return false; + } + return true; +} + +void XMLReader::readItemFromNode(QObject* item,QDomElement *node) +{ + + ObjectLoadingStateIntf* lf = dynamic_cast(item); + if(lf) lf->objectLoadStarted(); + for (int i=0;ichildNodes().count();i++){ + QDomElement currentNode =node->childNodes().at(i).toElement(); + if (currentNode.attribute("Type")=="Object"){ + readQObject(item,¤tNode); + }else if (currentNode.attribute("Type")=="Collection") + { + readCollection(item,¤tNode); + } + else readProperty(item,¤tNode); + } + if (lf) lf->objectLoadFinished(); + + BaseDesignIntf* baseObj = dynamic_cast(item); + if(baseObj) { + foreach(QGraphicsItem* item,baseObj->childItems()){ + BaseDesignIntf* baseItem = dynamic_cast(item); + if (baseItem) baseItem->parentObjectLoadFinished(); + } + } +} + +QString XMLReader::lastError() +{ + return m_error; +} + +bool XMLReader::extractFirstNode() +{ + if (m_firstNode.isNull()){ + if (m_doc->childNodes().count()==0){ + if (!prepareReader(m_doc.data())) return false; + } + m_firstNode = m_doc->documentElement(); + if (!m_firstNode.hasAttributes()) + m_firstNode = m_firstNode.firstChildElement(); + } + return !m_firstNode.isNull(); +} + +void XMLReader::readProperty(QObject *item, QDomElement *node) +{ + item->setProperty(node->nodeName().toLatin1(),getValue(node)); +} + +QVariant XMLReader::getValue(QDomElement *node) +{ + CreateSerializator creator = 0; + try { + creator=XMLAbstractSerializatorFactory::instance().objectCreator( + node->attribute("Type") + ); + } catch(ReportError &e){ + qDebug()<attribute("Type")<serializator(creator(m_doc.data(),node)); + return serializator->loadValue(); + } + return QVariant(); +} + +void XMLReader::readQObject(QObject* item, QDomElement* node) +{ + QObject* childItem = qvariant_cast(item->property(node->nodeName().toLatin1())); + if (childItem) + readItemFromNode(childItem,node); +} + +void XMLReader::readCollection(QObject *item, QDomElement *node) +{ + ICollectionContainer* collection = dynamic_cast(item); + if (collection){ + QString collectionName = node->nodeName(); + for(int i=0;ichildNodes().count();i++){ + QDomElement currentNode =node->childNodes().at(i).toElement(); + QObject* obj = collection->createElement(collectionName,currentNode.attribute("ClassName")); + if (obj) + readItemFromNode(obj,¤tNode); + } + collection->collectionLoadFinished(collectionName); + } +} + +FileXMLReader::FileXMLReader(QString fileName) + : m_fileName(fileName) +{ +} + +bool FileXMLReader::prepareReader(QDomDocument *doc) +{ + if (!m_fileName.isEmpty()){ + QFile source(m_fileName); + if (source.open(QFile::ReadOnly)) { + doc->setContent(&source); + } else {m_error=QString(QObject::tr("File %1 not opened")).arg(m_fileName); return false;} + } + return true; +} + +bool StringXMLreader::prepareReader(QDomDocument *doc) +{ + if (!m_content.isEmpty()){ + doc->setContent(m_content); + }else {m_error = QString(QObject::tr("Content string is empty")); return false;} + return true; +} + +bool ByteArrayXMLReader::prepareReader(QDomDocument *doc) +{ + if (m_content){ + doc->setContent(*m_content); + } else {m_error = QString(QObject::tr("Content is empty")); return false;} + return true; +} + +} diff --git a/src/serializators/lrxmlreader.h b/src/serializators/lrxmlreader.h new file mode 100644 index 0000000..f677c68 --- /dev/null +++ b/src/serializators/lrxmlreader.h @@ -0,0 +1,104 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRXMLREADER_H +#define LRXMLREADER_H + +#include +#include + +#include "serializators/lrxmlwriter.h" +#include "lrdesignelementsfactory.h" + +namespace LimeReport{ + +class XMLReader : public ItemsReaderIntf +{ +public: + XMLReader(); + XMLReader(QSharedPointer doc); +protected: + + virtual bool first(); + virtual bool next(); + virtual bool prior(); + virtual QString itemType(); + virtual QString itemClassName(); + virtual bool readItem(QObject *item); + virtual int firstLevelItemsCount(); + virtual bool prepareReader(QDomDocument *doc); + + void readItemFromNode(QObject *item, QDomElement *node); + void readProperty(QObject *item, QDomElement *node); + void readQObject(QObject *item, QDomElement *node); + void readCollection(QObject *item, QDomElement *node); + QVariant getValue(QDomElement *node); + + virtual QString lastError(); +protected: + bool extractFirstNode(); + QString m_error; +private: + QSharedPointer m_doc; + QDomElement m_curNode; + QDomElement m_firstNode; +}; + +class FileXMLReader : public XMLReader{ +public: + static ItemsReaderIntf::Ptr create(QString fileName){ return ItemsReaderIntf::Ptr(new FileXMLReader(fileName));} +protected: + virtual bool prepareReader(QDomDocument *doc); +private: + FileXMLReader(QString fileName); + QString m_fileName; +}; + +class StringXMLreader : public XMLReader{ +public: + static ItemsReaderIntf::Ptr create(QString content){ return ItemsReaderIntf::Ptr(new StringXMLreader(content));} +protected: + virtual bool prepareReader(QDomDocument *doc); +private: + StringXMLreader(QString content) : m_content(content){} + QString m_content; +}; + +class ByteArrayXMLReader : public XMLReader{ +public: + static ItemsReaderIntf::Ptr create(QByteArray* content){ return ItemsReaderIntf::Ptr(new ByteArrayXMLReader(content));} +protected: + virtual bool prepareReader(QDomDocument *doc); +private: + ByteArrayXMLReader(QByteArray* content): m_content(content){} + QByteArray* m_content; +}; + +} +#endif // LRXMLREADER_H diff --git a/src/serializators/lrxmlserializatorsfactory.h b/src/serializators/lrxmlserializatorsfactory.h new file mode 100644 index 0000000..5d76e06 --- /dev/null +++ b/src/serializators/lrxmlserializatorsfactory.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRXMLABSTRACTSERIALIZATORFABRIC_H +#define LRXMLABSTRACTSERIALIZATORFABRIC_H + +#include "lrserializatorintf.h" +#include "lrsimpleabstractfactory.h" + +#include + +namespace LimeReport{ + +typedef SerializatorIntf* (*CreateSerializator)(QDomDocument *doc, QDomElement *parentNode); + +class XMLAbstractSerializatorFactory: public SimpleAbstractFactory +{ +private: + friend class Singleton; +public: + XMLAbstractSerializatorFactory(){} + ~XMLAbstractSerializatorFactory(){} + XMLAbstractSerializatorFactory(const XMLAbstractSerializatorFactory&){} + XMLAbstractSerializatorFactory& operator = (const XMLAbstractSerializatorFactory&){return *this;} +}; + +} + +#endif // LRXMLABSTRACTSERIALIZATORFABRIC_H diff --git a/src/serializators/lrxmlwriter.cpp b/src/serializators/lrxmlwriter.cpp new file mode 100644 index 0000000..84beaee --- /dev/null +++ b/src/serializators/lrxmlwriter.cpp @@ -0,0 +1,222 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "lrxmlwriter.h" +#include "lrbasedesignintf.h" +#include "serializators/lrxmlserializatorsfactory.h" +#include "lrcollection.h" +#include + +namespace LimeReport{ + +XMLWriter::XMLWriter() : m_doc(new QDomDocument) +{ + m_rootElement=m_doc->createElement("Report"); + m_doc->appendChild(m_rootElement); +} + +XMLWriter::XMLWriter(QSharedPointer doc) : m_doc(doc){ + m_rootElement=m_doc->createElement("Report"); + m_doc->appendChild(m_rootElement); +} + +void XMLWriter::putItem(QObject *item) +{ + QDomElement node=putQObjectItem(item->metaObject()->className(),item); + if (!replaceNode(node,item)) m_rootElement.appendChild(node); +} + +QString XMLWriter::extractClassName(QObject *item) +{ + BaseDesignIntf* baseItem = dynamic_cast(item); + if(baseItem) return baseItem->storageTypeName(); + else return item->metaObject()->className(); +} + +void XMLWriter::putChildQObjectItem(QString name, QObject *item, QDomElement *parentNode) +{ + QDomElement itemNode = m_doc->createElement(name); + itemNode.setAttribute("ClassName",extractClassName(item)); + itemNode.setAttribute("Type","Object"); + if (parentNode) parentNode->appendChild(itemNode); + saveProperties(item,&itemNode); +} + +bool XMLWriter::setContent(QString fileName) +{ + QFile xmlFile(fileName); + if (xmlFile.open(QFile::ReadOnly)){ + return m_doc->setContent(&xmlFile); + } + return false; +} + +bool XMLWriter::saveToFile(QString fileName) +{ + if ((m_doc->childNodes().count()==0)||fileName.isEmpty()) return false; + QFile xmlFile(fileName); + if (xmlFile.open(QFile::WriteOnly)) { + QTextStream buffer(&xmlFile); + m_doc->save(buffer,2); + xmlFile.close(); + return true; + } + return false; +} + +QString XMLWriter::saveToString() +{ + QString res; + QTextStream buffer(&res); + m_doc->save(buffer,2); + return res; +} + +QDomElement XMLWriter::putQObjectItem(QString name, QObject *item) +{ + Q_UNUSED(name) + QDomElement itemNode = m_doc->createElement("object"); + itemNode.setAttribute("ClassName",extractClassName(item)); + itemNode.setAttribute("Type","Object"); + saveProperties(item,&itemNode); + return itemNode; +} + +void XMLWriter::saveProperty(QString name, QObject* item, QDomElement *node) +{ + CreateSerializator creator=0; + + if (isCollection(name,item)) { saveCollection(name,item,node); return;} + if (isQObject(name,item)) { + if (qvariant_cast(item->property(name.toLatin1()))) + putQObjectProperty(name,qvariant_cast(item->property(name.toLatin1())),node); + else { + qDebug()<<"Warnig property can`t be casted to QObject"<property(name.toLatin1()).typeName() + ); + } catch (LimeReport::ReportError &exception){ + qDebug()<<"class name ="<metaObject()->className() + <<"property name="<elementsCount(propertyName);i++){ + putCollectionItem(collection->elementAt(propertyName,i),&collectionNode); + } + + node->appendChild(collectionNode); +} + +bool XMLWriter::isQObject(QString propertyName, QObject *item) +{ + QMetaProperty prop=item->metaObject()->property(item->metaObject()->indexOfProperty(propertyName.toLatin1())); + return QMetaType::type(prop.typeName())==QMetaType::QObjectStar; +} + +bool XMLWriter::replaceNode(QDomElement node, QObject* item) +{ + QDomElement element = m_rootElement.firstChildElement(item->metaObject()->className()); + while (!element.isNull()){ + QDomElement objectName = element.firstChildElement(QLatin1String("objectName")); + if (!objectName.isNull()&&(objectName.text()==item->objectName())){ + QDomElement removeElement=element; + element=element.nextSiblingElement(item->metaObject()->className()); + m_rootElement.replaceChild(node,removeElement); + return true; + } + else element=element.nextSiblingElement(item->metaObject()->className()); + } + return false; +} + +void XMLWriter::putCollectionItem(QObject *item, QDomElement *parentNode) +{ + putChildQObjectItem("item",item,parentNode); +} + +void XMLWriter::putQObjectProperty(QString propertyName, QObject* item, QDomElement* parentNode) +{ + putChildQObjectItem(propertyName,item,parentNode); +} + +} + + + + + + + + diff --git a/src/serializators/lrxmlwriter.h b/src/serializators/lrxmlwriter.h new file mode 100644 index 0000000..9a814d6 --- /dev/null +++ b/src/serializators/lrxmlwriter.h @@ -0,0 +1,71 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef LRXMLWRITER_H +#define LRXMLWRITER_H + +#include +#include "serializators/lrstorageintf.h" +#include "serializators/lrxmlserializatorsfactory.h" +#include "lrbasedesignintf.h" + +namespace LimeReport{ + +class XMLWriter : public ItemsWriterIntf +{ +public: + XMLWriter(); + XMLWriter(QSharedPointer doc); + ~XMLWriter() {} +private: + virtual void putItem(QObject* item); + virtual bool saveToFile(QString fileName); + virtual QString saveToString(); + QDomElement putQObjectItem(QString name, QObject* item); + void putChildQObjectItem(QString name, QObject* item, QDomElement* parentNode); + void putCollectionItem(QObject* item, QDomElement* parentNode=0); + void putQObjectProperty(QString propertyName, QObject *item, QDomElement* parentNode=0); + void saveProperties(QObject* item, QDomElement* node); + bool setContent(QString fileName); + void saveProperty(QString name, QObject* item, QDomElement* node); + bool enumOrFlag(QString name, QObject* item); + QString extractClassName(QObject* item); + bool isCollection(QString propertyName, QObject *item); + void saveCollection(QString propertyName, QObject *item, QDomElement *node); + bool isQObject(QString propertyName, QObject *item); + bool replaceNode(QDomElement node, QObject *item); +private: + QSharedPointer m_doc; + QString m_fileName; + QDomElement m_rootElement; +}; + +} + +#endif // LRXMLWRITER_H diff --git a/src/waitform.cpp b/src/waitform.cpp new file mode 100644 index 0000000..f359918 --- /dev/null +++ b/src/waitform.cpp @@ -0,0 +1,44 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#include "waitform.h" +#include "ui_waitform.h" +#include + +WaitForm::WaitForm(QWidget *parent) : + QDialog(parent), + ui(new Ui::WaitForm) +{ + ui->setupUi(this); +} + +WaitForm::~WaitForm() +{ + delete ui; +} diff --git a/src/waitform.h b/src/waitform.h new file mode 100644 index 0000000..658ce3b --- /dev/null +++ b/src/waitform.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library 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. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library 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. * + ****************************************************************************/ +#ifndef WAITFORM_H +#define WAITFORM_H + +#include + +namespace Ui { +class WaitForm; +} + +class WaitForm : public QDialog +{ + Q_OBJECT + +public: + explicit WaitForm(QWidget *parent = 0); + ~WaitForm(); + +private: + Ui::WaitForm *ui; +}; + +#endif // WAITFORM_H diff --git a/src/waitform.ui b/src/waitform.ui new file mode 100644 index 0000000..4549ef8 --- /dev/null +++ b/src/waitform.ui @@ -0,0 +1,58 @@ + + + WaitForm + + + + 0 + 0 + 186 + 95 + + + + + 0 + 0 + + + + Wait + + + false + + + + + + + 0 + 0 + + + + + + + :/report/images/hourglass + + + true + + + + + + + Please wait ... + + + + + + + + + +