diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2018-05-18 16:45:35 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2018-05-18 16:45:35 +0200 |
commit | 3f8c8702ea295f39357e7c66f46e5138f56bcc9f (patch) | |
tree | 9ca65a7f94d544ba4b36f239c4a48852ad8a7b09 | |
parent | 5fce76074c01e52a22151133a1e3a2cf71cfe535 (diff) | |
parent | df1a619d65d8e5db91f3c8db46b00872b461e334 (diff) |
Merge remote-tracking branch 'origin/5.9' into 5.11
Change-Id: I20cf741f5b07426ad5113eb8c52f144102c331ce
70 files changed, 2394 insertions, 1746 deletions
diff --git a/LICENSE.GPLv3 b/LICENSE.GPLv3 deleted file mode 100644 index 71c4ad49c..000000000 --- a/LICENSE.GPLv3 +++ /dev/null @@ -1,686 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - - The Qt Toolkit is Copyright (C) 2015 The Qt Company Ltd. - Contact: http://www.qt.io/licensing/ - - You may use, distribute and copy the Qt Toolkit under the terms of - GNU Lesser General Public License version 3. That license references - the General Public License version 3, that is displayed below. Other - portions of the Qt Toolkit may be licensed directly under this license. - -------------------------------------------------------------------------- - - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - -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: - - <program> Copyright (C) <year> <name of author> - 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 -<http://www.gnu.org/licenses/>. - - 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 -<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/LICENSE.LGPLv21 b/LICENSE.LGPLv21 deleted file mode 100644 index 15a208b48..000000000 --- a/LICENSE.LGPLv21 +++ /dev/null @@ -1,514 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - - The Qt Toolkit is Copyright (C) 2016 The Qt Company Ltd. - Contact: http://www.qt.io/licensing/ - - You may use, distribute and copy the Qt Toolkit under the terms of - GNU Lesser General Public License version 2.1, which is displayed below. - -------------------------------------------------------------------------- - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -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 this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser 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 Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "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 -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY 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 -LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - <one line to give the library's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - 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 2.1 of the License, or (at your option) any later version. - - 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - <signature of Ty Coon>, 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/LICENSE.LGPLv3 b/LICENSE.LGPLv3 deleted file mode 100644 index 849103ad9..000000000 --- a/LICENSE.LGPLv3 +++ /dev/null @@ -1,175 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - - The Qt Toolkit is Copyright (C) 2016 The Qt Company Ltd. - Contact: http://www.qt.io/licensing/ - - You may use, distribute and copy the Qt Toolkit under the terms of - GNU Lesser General Public License version 3, which is displayed below. - This license makes reference to the version 3 of the GNU General - Public License, which you can find in the LICENSE.GPLv3 file. - -------------------------------------------------------------------------- - - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/> -Everyone is permitted to copy and distribute verbatim copies of this -licensedocument, but changing it is not allowed. - -This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - -0. Additional Definitions. - - As used herein, “this License” refers to version 3 of the GNU Lesser -General Public License, and the “GNU GPL” refers to version 3 of the -GNU General Public License. - - “The Library” refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An “Application” is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A “Combined Work” is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the “Linked -Version”. - - The “Minimal Corresponding Source” for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The “Corresponding Application Code” for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - -1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - -2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort - to ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - -3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this - license document. - -4. Combined Works. - - You may convey a Combined Work under terms of your choice that, taken -together, effectively do not restrict modification of the portions of -the Library contained in the Combined Work and reverse engineering for -debugging such modifications, if you also do each of the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this - license document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of - this License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with - the Library. A suitable mechanism is one that (a) uses at run - time a copy of the Library already present on the user's - computer system, and (b) will operate properly with a modified - version of the Library that is interface-compatible with the - Linked Version. - - e) Provide Installation Information, but only if you would - otherwise be required to provide such information under section 6 - of the GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the Application - with a modified version of the Linked Version. (If you use option - 4d0, the Installation Information must accompany the Minimal - Corresponding Source and Corresponding Application Code. If you - use option 4d1, you must provide the Installation Information in - the manner specified by section 6 of the GNU GPL for conveying - Corresponding Source.) - -5. Combined Libraries. - - You may place library facilities that are a work based on the Library -side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities, conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of - it is a work based on the Library, and explaining where to find - the accompanying uncombined form of the same work. - -6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser 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 Library -as you received it specifies that a certain numbered version of the -GNU Lesser General Public License “or any later version” applies to -it, you have the option of following the terms and conditions either -of that published version or of any later version published by the -Free Software Foundation. If the Library as you received it does not -specify a version number of the GNU Lesser General Public License, -you may choose any version of the GNU Lesser General Public License -ever published by the Free Software Foundation. - -If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the Library. - diff --git a/build_scripts/main.py b/build_scripts/main.py index fd5998480..b22249abb 100644 --- a/build_scripts/main.py +++ b/build_scripts/main.py @@ -967,6 +967,15 @@ class pyside_build(_build): moduleSubSet += ';' moduleSubSet += m cmake_cmd.append("-DMODULES={}".format(moduleSubSet)) + if OPTION_SKIP_MODULES: + skip_modules = '' + for m in OPTION_SKIP_MODULES.split(','): + if m.startswith('Qt'): + m = m[2:] + if skip_modules: + skip_modules += ';' + skip_modules += m + cmake_cmd.append("-DSKIP_MODULES={}".format(skip_modules)) # Add source location for generating documentation cmake_src_dir = OPTION_QT_SRC if OPTION_QT_SRC else qtSrcDir cmake_cmd.append("-DQT_SRC_DIR={}".format(cmake_src_dir)) diff --git a/build_scripts/options.py b/build_scripts/options.py index 6472c664d..80c9041e4 100644 --- a/build_scripts/options.py +++ b/build_scripts/options.py @@ -72,6 +72,7 @@ OPTION_REUSE_BUILD = has_option("reuse-build") OPTION_SKIP_CMAKE = has_option("skip-cmake") OPTION_SKIP_MAKE_INSTALL = has_option("skip-make-install") OPTION_SKIP_PACKAGING = has_option("skip-packaging") +OPTION_SKIP_MODULES = option_value("skip-modules") OPTION_MODULE_SUBSET = option_value("module-subset") OPTION_RPATH_VALUES = option_value("rpath") OPTION_QT_CONF_PREFIX = option_value("qt-conf-prefix") diff --git a/build_scripts/platforms/macos.py b/build_scripts/platforms/macos.py index a45192667..936f4ca90 100644 --- a/build_scripts/platforms/macos.py +++ b/build_scripts/platforms/macos.py @@ -49,6 +49,16 @@ def prepare_standalone_package_macos(self, executables, vars): return False return True + # Filter out debug plugins and qml plugins in the + # debug_and_release config. + no_copy_debug = True + def file_variant_filter(file_name, file_full_path): + if self.qtinfo.build_type != 'debug_and_release': + return True + if file_name.endswith('_debug.dylib') and no_copy_debug: + return False + return True + # <qt>/lib/* -> <setup>/PySide2/Qt/lib if self.qt_is_framework_build(): framework_built_modules = [ @@ -71,10 +81,23 @@ def prepare_standalone_package_macos(self, executables, vars): return general_dir_filter(dir_name, parent_full_path, dir_full_path) + # Filter out debug frameworks in the + # debug_and_release config. + no_copy_debug = True + def framework_variant_filter(file_name, file_full_path): + if self.qtinfo.build_type != 'debug_and_release': + return True + dir_path = os.path.dirname(file_full_path) + in_framework = dir_path.endswith("Versions/5") + if file_name.endswith('_debug') and in_framework and no_copy_debug: + return False + return True + copydir("{qt_lib_dir}", "{pyside_package_dir}/PySide2/Qt/lib", recursive=True, vars=vars, ignore=["*.la", "*.a", "*.cmake", "*.pc", "*.prl"], - dir_filter_function=framework_dir_filter) + dir_filter_function=framework_dir_filter, + file_filter_function=framework_variant_filter) # Fix rpath for WebEngine process executable. The already # present rpath does not work because it assumes a symlink @@ -102,6 +125,7 @@ def prepare_standalone_package_macos(self, executables, vars): "{pyside_package_dir}/PySide2/Qt/lib", filter=accepted_modules, ignore=ignored_modules, + file_filter_function=file_variant_filter, recursive=True, vars=vars, force_copy_symlinks=True) if self.is_webengine_built(built_modules): @@ -137,6 +161,7 @@ def prepare_standalone_package_macos(self, executables, vars): filter=["*.dylib"], recursive=True, dir_filter_function=general_dir_filter, + file_filter_function=file_variant_filter, vars=vars) # <qt>/qml/* -> <setup>/PySide2/Qt/qml @@ -146,6 +171,7 @@ def prepare_standalone_package_macos(self, executables, vars): recursive=True, force=False, dir_filter_function=general_dir_filter, + file_filter_function=file_variant_filter, vars=vars) # <qt>/translations/* -> <setup>/PySide2/Qt/translations diff --git a/build_scripts/platforms/windows_desktop.py b/build_scripts/platforms/windows_desktop.py index 6a18659c5..f4b4aed6e 100644 --- a/build_scripts/platforms/windows_desktop.py +++ b/build_scripts/platforms/windows_desktop.py @@ -180,8 +180,6 @@ def prepare_packages_win32(self, vars): qt_artifacts_permanent = [ "opengl*.dll", "d3d*.dll", - "libEGL*.dll", - "libGLESv2*.dll", "designer.exe", "linguist.exe", "lrelease.exe", @@ -189,6 +187,21 @@ def prepare_packages_win32(self, vars): "lconvert.exe", "qtdiag.exe" ] + + # Choose which EGL library variants to copy. + qt_artifacts_egl = [ + "libEGL{}.dll", + "libGLESv2{}.dll" + ] + if self.qtinfo.build_type != 'debug_and_release': + egl_suffix = '*' + elif self.debug: + egl_suffix = 'd' + else: + egl_suffix = '' + qt_artifacts_egl = [a.format(egl_suffix) for a in qt_artifacts_egl] + qt_artifacts_permanent += qt_artifacts_egl + copydir("{qt_bin_dir}", "{pyside_package_dir}/PySide2", filter=qt_artifacts_permanent, recursive=False, vars=vars) @@ -273,18 +286,21 @@ def prepare_packages_win32(self, vars): # <qt>/qml/* -> <setup>/PySide2/qml qml_dll_patterns = ["*{}.dll"] qml_ignore_patterns = qml_dll_patterns + [pdb_pattern] - # Remove the "{}" from the patterns qml_ignore = [a.format('') for a in qml_ignore_patterns] - if copy_pdbs: - qml_dll_patterns += [pdb_pattern] - qml_ignore = [a.format('') for a in qml_dll_patterns] - qml_dll_filter = functools.partial(qt_build_config_filter, - qml_dll_patterns) + + # Copy all files that are not dlls and pdbs (.qml, qmldir). copydir("{qt_qml_dir}", "{pyside_package_dir}/PySide2/qml", ignore=qml_ignore, force=False, recursive=True, vars=vars) + + if copy_pdbs: + qml_dll_patterns += [pdb_pattern] + qml_dll_filter = functools.partial(qt_build_config_filter, + qml_dll_patterns) + + # Copy all dlls (and possibly pdbs). copydir("{qt_qml_dir}", "{pyside_package_dir}/PySide2/qml", file_filter_function=qml_dll_filter, force=False, diff --git a/build_scripts/utils.py b/build_scripts/utils.py index af40916b7..2dffd345c 100644 --- a/build_scripts/utils.py +++ b/build_scripts/utils.py @@ -409,7 +409,7 @@ def make_file_writable_by_owner(path): current_permissions = stat.S_IMODE(os.lstat(path).st_mode) os.chmod(path, current_permissions | stat.S_IWUSR) -def rmtree(dirname): +def rmtree(dirname, ignore=False): def handleRemoveReadonly(func, path, exc): excvalue = exc[1] if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES: @@ -417,7 +417,7 @@ def rmtree(dirname): func(path) else: raise - shutil.rmtree(dirname, ignore_errors=False, onerror=handleRemoveReadonly) + shutil.rmtree(dirname, ignore_errors=ignore, onerror=handleRemoveReadonly) def run_process_output(args, initial_env=None): if initial_env is None: @@ -1081,3 +1081,39 @@ def get_python_dict(python_script_path): print("get_python_dict: Couldn't get dict from python " "file: {}.".format(python_script_path)) raise + +def install_pip_dependencies(env_pip, packages): + for p in packages: + run_instruction([env_pip, "install", p], "Failed to install " + p) + +def get_qtci_virtualEnv(python_ver, host, hostArch, targetArch): + _pExe = "python" + _env = "env" + str(python_ver) + env_python = _env + "/bin/python" + env_pip = _env + "/bin/pip" + + if host == "Windows": + print("New virtualenv to build " + targetArch + " in " + hostArch + " host.") + _pExe = "python.exe" + # With windows we are creating building 32-bit target in 64-bit host + if hostArch == "X86_64" and targetArch == "X86": + if python_ver == "3": + _pExe = os.path.join(os.getenv("PYTHON3_32_PATH"), "python.exe") + else: + _pExe = os.path.join(os.getenv("PYTHON2_32_PATH"), "python.exe") + else: + if python_ver == "3": + _pExe = os.path.join(os.getenv("PYTHON3_PATH"), "python.exe") + env_python = _env + "\\Scripts\\python.exe" + env_pip = _env + "\\Scripts\\pip.exe" + else: + if python_ver == "3": + _pExe = "python3" + return(_pExe, _env, env_pip, env_python) + +def run_instruction(instruction, error): + print("Running Coin instruction: " + ' '.join(str(e) for e in instruction)) + result = subprocess.call(instruction) + if result != 0: + print("ERROR : " + error) + exit(result) diff --git a/coin_build_instructions.py b/coin_build_instructions.py new file mode 100644 index 000000000..175513570 --- /dev/null +++ b/coin_build_instructions.py @@ -0,0 +1,100 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# +from build_scripts.utils import has_option +from build_scripts.utils import option_value +from build_scripts.utils import install_pip_dependencies +from build_scripts.utils import get_qtci_virtualEnv +from build_scripts.utils import run_instruction +from build_scripts.utils import rmtree +import os + +# Values must match COIN thrift +CI_HOST_OS = option_value("os") +CI_TARGET_OS = option_value("targetOs") +CI_HOST_ARCH = option_value("hostArch") +CI_TARGET_ARCH = option_value("targetArch") +CI_HOST_OS_VER = option_value("osVer") +CI_ENV_INSTALL_DIR = option_value("instdir") +CI_ENV_AGENT_DIR = option_value("agentdir") +CI_COMPILER = option_value("compiler") +CI_FEATURES = [] +_ci_features = option_value("features") +if _ci_features is not None: + for f in _ci_features.split(', '): + CI_FEATURES.append(f) +CI_RELEASE_CONF = has_option("packaging") + + +def call_setup(python_ver): + _pExe, _env, env_pip, env_python = get_qtci_virtualEnv(python_ver, CI_HOST_OS, CI_HOST_ARCH, CI_TARGET_ARCH) + rmtree(_env, True) + run_instruction(["virtualenv", "-p", _pExe, _env], "Failed to create virtualenv") + install_pip_dependencies(env_pip, ["six", "wheel"]) + cmd = [env_python, "setup.py"] + # With 5.11 CI will create two sets of release binaries, one with msvc 2015 and one with msvc 2017 + # we shouldn't release the 2015 version. + if CI_RELEASE_CONF and CI_COMPILER not in ["MSVC2017"]: + cmd += ["bdist_wheel", "--standalone"] + else: + cmd += ["build"] + if CI_HOST_OS == "MacOS": + cmd += ["--qmake=" + CI_ENV_INSTALL_DIR + "/bin/qmake"] + elif CI_HOST_OS == "Windows": + + cmd += ["--qmake=" + CI_ENV_INSTALL_DIR + "\\bin\\qmake.exe", + "--openssl=C:\\openssl\\bin"] + else: + cmd += ["--qmake=" + CI_ENV_INSTALL_DIR + "/bin/qmake"] + cmd += ["--build-tests", + "--jobs=4", + "--verbose-build", + "--snapshot-build"] + + run_instruction(cmd, "Failed to run setup.py") + +def run_build_instructions(): + # Uses default python, hopefully we have python2 installed on all hosts + call_setup("") + + # In case of packaging build, we have to build also python3 wheel + if CI_RELEASE_CONF and CI_HOST_OS_VER not in ["RHEL_6_6"]: + call_setup("3") + +if __name__ == "__main__": + run_build_instructions() diff --git a/coin_test_instructions.py b/coin_test_instructions.py new file mode 100644 index 000000000..29b664542 --- /dev/null +++ b/coin_test_instructions.py @@ -0,0 +1,82 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# +from build_scripts.utils import has_option +from build_scripts.utils import option_value +from build_scripts.utils import install_pip_dependencies +from build_scripts.utils import get_qtci_virtualEnv +from build_scripts.utils import run_instruction +from build_scripts.utils import rmtree +import os + +# Values must match COIN thrift +CI_HOST_OS = option_value("os") +CI_TARGET_OS = option_value("targetOs") +CI_HOST_ARCH = option_value("hostArch") +CI_TARGET_ARCH = option_value("targetArch") +CI_HOST_OS_VER = option_value("osVer") +CI_ENV_INSTALL_DIR = option_value("instdir") +CI_ENV_AGENT_DIR = option_value("agentdir") or "." +CI_COMPILER = option_value("compiler") +CI_FEATURES = [] +_ci_features = option_value("features") +if _ci_features is not None: + for f in _ci_features.split(', '): + CI_FEATURES.append(f) + +CI_RELEASE_CONF = has_option("packaging") + +def call_testrunner(python_ver, buildnro): + _pExe, _env, env_pip, env_python = get_qtci_virtualEnv(python_ver, CI_HOST_OS, CI_HOST_ARCH, CI_TARGET_ARCH) + rmtree(_env, True) + run_instruction(["virtualenv", "-p", _pExe, _env], "Failed to create virtualenv") + install_pip_dependencies(env_pip, ["six", "wheel"]) + cmd = [env_python, "testrunner.py", "test", + "--blacklist", "build_history/blacklist.txt", + "--buildno=" + buildnro] + run_instruction(cmd, "Failed to run testrunner.py") + +def run_test_instructions(): + os.chdir(CI_ENV_AGENT_DIR) + call_testrunner("", "0") + # We know that second build was with python3 + if CI_RELEASE_CONF and CI_HOST_OS_VER not in ["RHEL_6_6"]: + call_testrunner("3", "1") + +if __name__ == "__main__": + run_test_instructions() diff --git a/examples/samplebinding/CMakeLists.txt b/examples/samplebinding/CMakeLists.txt new file mode 100644 index 000000000..03ab85754 --- /dev/null +++ b/examples/samplebinding/CMakeLists.txt @@ -0,0 +1,233 @@ +cmake_minimum_required(VERSION 3.1) +cmake_policy(VERSION 3.1) + +# Enable policy to not use RPATH settings for install_name on macOS. +if(POLICY CMP0068) + cmake_policy(SET CMP0068 NEW) +endif() + +# Consider changing the project name to something relevant for you. +project(SampleBinding) + +# ================================ General configuration ====================================== + +# Set CPP standard to C++11 minimum. +set(CMAKE_CXX_STANDARD 11) + +# The sample library for which we will create bindings. You can change the name to something +# relevant for your project. +set(sample_library "libuniverse") + +# The name of the generated bindings module (as imported in Python). You can change the name +# to something relevant for your project. +set(bindings_library "Universe") + +# The header file with all the types and functions for which bindings will be generated. +# Usually it simply includes other headers of the library you are creating bindings for. +set(wrapped_header ${CMAKE_SOURCE_DIR}/bindings.h) + +# The typesystem xml file which defines the relationships between the C++ types / functions +# and the corresponding Python equivalents. +set(typesystem_file ${CMAKE_SOURCE_DIR}/bindings.xml) + +# Specify which C++ files will be generated by shiboken. This includes the module wrapper +# and a '.cpp' file per C++ type. These are needed for generating the module shared +# library. +set(generated_sources + ${CMAKE_CURRENT_BINARY_DIR}/${bindings_library}/universe_module_wrapper.cpp + ${CMAKE_CURRENT_BINARY_DIR}/${bindings_library}/icecream_wrapper.cpp + ${CMAKE_CURRENT_BINARY_DIR}/${bindings_library}/truck_wrapper.cpp) + + +# ================================== Shiboken detection ====================================== + + +# Macro to get various pyside / python include / link flags and paths. +# Uses the not entirely supported utils/pyside2_config.py file. +macro(pyside2_config option output_var) + if(${ARGC} GREATER 2) + set(is_list ${ARGV2}) + else() + set(is_list "") + endif() + + execute_process( + COMMAND python "${CMAKE_SOURCE_DIR}/../utils/pyside2_config.py" ${option} + OUTPUT_VARIABLE ${output_var} + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if ("${${output_var}}" STREQUAL "") + message(FATAL_ERROR "Error: Calling pyside2_config.py ${option} returned no output.") + endif() + if(is_list) + string (REPLACE " " ";" ${output_var} "${${output_var}}") + endif() +endmacro() + +# Query for the shiboken path, Python path, include paths and linker flags. +pyside2_config(--pyside2 pyside2_path) +pyside2_config(--python-include python_include_dir) +pyside2_config(--shiboken-include shiboken_include_dir 1) +pyside2_config(--shiboken-shared-libraries-cmake shiboken_shared_libraries 0) +pyside2_config(--python-link-cmake python_linking_data 0) + +set(shiboken_path "${pyside2_path}/shiboken2${CMAKE_EXECUTABLE_SUFFIX}") +if(NOT EXISTS ${shiboken_path}) + message(FATAL_ERROR "Shiboken executable not found at path: ${shiboken_path}") +endif() + + +# ==================================== RPATH configuration ==================================== + + +# ============================================================================================= +# !!! (The section below is deployment related, so in a real world application you will want to +# take care of this properly with some custom script or tool). +# ============================================================================================= +# Enable rpaths so that the built shared libraries find their dependencies. +set(CMAKE_SKIP_BUILD_RPATH FALSE) +set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) +set(CMAKE_INSTALL_RPATH ${pyside2_path} ${CMAKE_CURRENT_SOURCE_DIR}) +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) +# ============================================================================================= +# !!! End of dubious section. +# ============================================================================================= + + +# =============================== CMake target - sample_library =============================== + + +# Define the sample shared library for which we will create bindings. +set(${sample_library}_sources icecream.cpp truck.cpp) +add_library(${sample_library} SHARED ${${sample_library}_sources}) +set_property(TARGET ${sample_library} PROPERTY PREFIX "") + +# Needed mostly on Windows to export symbols, and create a .lib file, otherwise the binding +# library can't link to the sample library. +target_compile_definitions(${sample_library} PRIVATE BINDINGS_BUILD) + + +# ====================== Shiboken target for generating binding C++ files ==================== + + +# Set up the options to pass to shiboken. +set(shiboken_options --generator-set=shiboken --enable-parent-ctor-heuristic + --enable-return-value-heuristic --use-isnull-as-nb_nonzero + --avoid-protected-hack + -I${CMAKE_SOURCE_DIR} + -T${CMAKE_SOURCE_DIR} + --output-directory=${CMAKE_CURRENT_BINARY_DIR} + ) + +set(generated_sources_dependencies ${wrapped_header} ${typesystem_file}) + +# Add custom target to run shiboken to generate the binding cpp files. +add_custom_command(OUTPUT ${generated_sources} + COMMAND ${shiboken_path} + ${shiboken_options} ${wrapped_header} ${typesystem_file} + DEPENDS ${generated_sources_dependencies} + IMPLICIT_DEPENDS CXX ${wrapped_header} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Running generator for ${typesystem_file}.") + + +# =============================== CMake target - bindings_library ============================= + + +# Set the cpp files which will be used for the bindings library. +set(${bindings_library}_sources ${generated_sources}) + +# Define and build the bindings library. +add_library(${bindings_library} MODULE ${${bindings_library}_sources}) + +# Apply relevant include and link flags. +target_include_directories(${bindings_library} PRIVATE ${python_include_dir}) +target_include_directories(${bindings_library} PRIVATE ${shiboken_include_dir}) +target_include_directories(${bindings_library} PRIVATE ${CMAKE_SOURCE_DIR}) + +target_link_libraries(${bindings_library} PRIVATE ${shiboken_shared_libraries}) +target_link_libraries(${bindings_library} PRIVATE ${sample_library}) + +# Adjust the name of generated module. +set_property(TARGET ${bindings_library} PROPERTY PREFIX "") +set_property(TARGET ${bindings_library} PROPERTY OUTPUT_NAME + "${bindings_library}${PYTHON_EXTENSION_SUFFIX}") +if(WIN32) + set_property(TARGET ${bindings_library} PROPERTY SUFFIX ".pyd") +endif() + +# Make sure the linker doesn't complain about not finding Python symbols on macOS. +if(APPLE) + set_target_properties(${bindings_library} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") +endif(APPLE) + +# Find and link to the python import library only on Windows. +# On Linux and macOS, the undefined symbols will get resolved by the dynamic linker +# (the symbols will be picked up in the Python executable). +if (WIN32) + list(GET python_linking_data 0 python_libdir) + list(GET python_linking_data 1 python_lib) + find_library(python_link_flags ${python_lib} PATHS ${python_libdir} HINTS ${python_libdir}) + target_link_libraries(${bindings_library} PRIVATE ${python_link_flags}) +endif() + + +# ================================= Dubious deployment section ================================ + + +if(WIN32) + # ========================================================================================= + # !!! (The section below is deployment related, so in a real world application you will + # want to take care of this properly (this is simply to eliminate errors that users usually + # encounter. + # ========================================================================================= + # Circumvent some "#pragma comment(lib)"s in "include/pyconfig.h" which might force to link + # against a wrong python shared library. + + set(python_versions_list 3 32 33 34 35 36 37 38) + set(python_additional_link_flags "") + foreach(ver ${python_versions_list}) + set(python_additional_link_flags + "${python_additional_link_flags} /NODEFAULTLIB:\"python${ver}_d.lib\"") + set(python_additional_link_flags + "${python_additional_link_flags} /NODEFAULTLIB:\"python${ver}.lib\"") + endforeach() + + set_target_properties(${bindings_library} + PROPERTIES LINK_FLAGS "${python_additional_link_flags}") + + # Add custom target to hard-link shiboken shared libraries into the build folder, so that + # the user doesn't have to set the PATH manually to point to the PySide2 package. + foreach(library_path ${shiboken_shared_libraries}) + string(REGEX REPLACE ".lib$" ".dll" library_path ${library_path}) + get_filename_component(base_name ${library_path} NAME) + file(TO_NATIVE_PATH ${library_path} source_path) + file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${base_name}" dest_path) + add_custom_command(OUTPUT "${base_name}" + COMMAND mklink /H "${dest_path}" "${source_path}" + DEPENDS ${library_path} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Creating hardlink to shiboken shared library ${base_name}") + + # Fake target that depends on the previous one, but has special ALL keyword, which means + # it will always be executed. + add_custom_target("fake_${base_name}" ALL DEPENDS ${base_name}) + endforeach() + # ========================================================================================= + # !!! End of dubious section. + # ========================================================================================= +endif() + +# ============================================================================================= +# !!! (The section below is deployment related, so in a real world application you will want to +# take care of this properly with some custom script or tool). +# ============================================================================================= +# Install the library and the bindings module into the source folder near the main.py file, so +# that the Python interpeter successfully imports the used module. +install(TARGETS ${bindings_library} ${sample_library} + LIBRARY DESTINATION ${CMAKE_CURRENT_SOURCE_DIR} + RUNTIME DESTINATION ${CMAKE_CURRENT_SOURCE_DIR} + ) +# ============================================================================================= +# !!! End of dubious section. +# ============================================================================================= diff --git a/examples/samplebinding/README.md b/examples/samplebinding/README.md new file mode 100644 index 000000000..85e96ddbe --- /dev/null +++ b/examples/samplebinding/README.md @@ -0,0 +1,223 @@ +# Sample bindings example + +This example showcases how to generate Python bindings for a +non-Qt C++ library. + +The example defines a CMake project that builds two libraries: +* `libuniverse` - a sample library with two C++ classes. +* `Universe` - the generated Python extension module that contains + bindings to the library above. + +The project file is structured in such a way that a user can copy-paste +in into their own project, and be able to build it with a minimal amount +of modifications. + +## Description + +The libuniverse library declares two classes: `Icecream` and `Truck`. + +`Icecream` objects have a flavor, and an accessor for returning the +flavor. + +`Truck` instances store a vector of `Icecream` objects, and have various +methods for adding new flavors, printing available flavors, delivering +icecream, etc. + +From a C++ perspective, `Icecream` instances are treated as +**object types** (pointer semantics) because the class declares virtual +methods. + +In contrast `Truck` does not define virtual methods and is treated as +a **value type** (copy semantics). + +Because `Truck` is a value type and it stores a vector of `Icecream` +pointers, the rule of three has to be taken into account (implement the +copy constructor, assignment operator, destructor). + +And due to `Icecream` objects being copyable, the type has to define an +implementation of the *clone()* method, to avoid type slicing issues. + +Both of these types and their methods will be exposed to Python by +generating CPython code. The code is generated by **shiboken** and +placed in separate ".cpp" files named after each C++ type. The code is +then compiled and linked into a shared library. The shared library is a +CPython extension module, which is loaded by the Python interpreter. + +Beacuse the C++ language has different semantics to Python, shiboken +needs help in figuring out how to generate the bindings code. This is +done by specifying a special XML file called a typesystem file. + +In the typesystem file you specify things like: + * which C++ primitive types should have bindings (int, bool, float) + * which C++ classes should have bindings (Icecream) and what kind of + semantics (value / object) + * Ownership rules (who deletes the C++ objects, C++ or Python) + * Code injection (for various special cases that shiboken doesn't know + about) + * Package name (name of package as imported from Python) + +In this example we declare `bool` and `std::string` as primitive types, +`Icecream` as an object type, `Truck` as a value type, +and the `clone()` and `addIcecreamFlavor(Icecream*)` need additional +info about who owns the parameter objects when passing them across +language boundaries (in this case C++ will delete the objects). + +After shiboken generates the C++ code and CMake makes an extension +module from the code, the types can be accessed in Python simply by +importing them using the original C++ names. + +``` +from Universe import Icecream, Truck +``` + +Constructing C++ wrapped objects is the same as in Python +``` +icecream = Icecream("vanilla") +truck = Truck() +``` + + +And actual C++ constructors are mapped to the Python `__init__` method. +``` +class VanillaChocolateIcecream(Icecream): + def __init__(self, flavor=""): + super(VanillaChocolateIcecream, self).__init__(flavor) +``` + + +C++ methods can be accessed as regular Python methods using the C++ +names +``` +truck.addIcecreamFlavor(icecream) +``` + + +Inheritance works as with regular Python classes, and virtual C++ +methods can be overridden simply by definining a method with the same +name as in the C++ class. +``` +class VanillaChocolateIcecream(Icecream): + # ... + def getFlavor(self): + return "vanilla sprinked with chocolate" + +``` + + +The `main.py` script demonstrates usages of these types. + +The CMake project file contains many comments explaining all the build +rules for those interested in the build process. + +## Building the project + +This example can only be built using **CMake**. +The following requirements need to be met: + +* A PySide2 package is installed into the current active Python + environment (system or virtualenv) +* A new enough version of CMake (**3.1+**). + +For Windows you will also need: +* a Visual Studio environment to be active in your terminal +* Correct visual studio architecture chosen (32 vs 64 bit) +* Make sure that your Python intepreter and bindings project build + configuration is the same (all Release, which is more likely, + or all Debug). + +The build uses the `pyside2_config.py` file to configure the project +using the current PySide2/Shiboken2 installation. + +### Using CMake + +You can build and run this example by executing the following commands +(slightly adapted to your file system layout) in a terminal: + +On macOS/Linux: +```bash +cd ~/pyside-setup/examples/samplebinding +mkdir build +cd build +cmake -H.. -B. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release +make +make install +python ../main.py +``` + +On Windows: +```bash +cd C:\pyside-setup\examples\samplebinding +mkdir build +cd build +cmake -H.. -B. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release +# or if you have jom available +# cmake -H.. -B. -G "NMake Makefiles JOM" -DCMAKE_BUILD_TYPE=Release +nmake # or jom +nmake install # or jom install +python ..\main.py +``` + +#### Windows troubleshooting + +It is possible that **CMake** can pick up the wrong compiler +for a different architecture, but it can be addressed explicitly +using the -G option: + +```bash +cmake -H.. -B. -G "Visual Studio 14 Win64" +``` + +If the `-G "Visual Studio 14 Win64"` option is used, a `sln` file +will be generated, and can be used with `MSBuild` +instead of `nmake/jom`. +The easiest way to both build and install in this case, is to use +the cmake executable: + +```bash +cmake --build . --target install --config Release +``` + +Note that using the "NMake Makefiles JOM" generator is preferred to +the MSBuild one, because the MSBuild one generates configs for both +Debug and Release, and this might lead to building errors if you +accidentally build the wrong config at least once. + +## Virtualenv Support + +If the python application is started from a terminal with an activated +python virtual environment, that environment's packages will be used for +the python module import process. +In this case, make sure that the bindings were built while the +`virtualenv` was active, so that the build system picks up the correct +python shared library and PySide2 / shiboken package. + +## Linux Shared Libraries Notes + +For this example's purpose, we link against the absolute path of the +dependent shared library `libshiboken` because the +installation of the library is done via a wheel, and there is +no clean solution to include symbolic links in a wheel package +(so that passing -lshiboken to the linker would work). + +## Windows Notes + +The build config of the bindings (Debug or Release) should match +the PySide2 build config, otherwise the application will not properly +work. + +In practice this means the only supported configurations are: + +1. release config build of the bindings + + PySide2 `setup.py` without `--debug` flag + `python.exe` for the + PySide2 build process + `python36.dll` for the linked in shared + library. +2. debug config build of the application + + PySide2 `setup.py` **with** `--debug` flag + `python_d.exe` for the + PySide2 build process + `python36_d.dll` for the linked in shared + library. + +This is necessary because all the shared libraries in question have to +link to the same C++ runtime library (`msvcrt.dll` or `msvcrtd.dll`). +To make the example as self-contained as possible, the shared libraries +in use (`pyside2.dll`, `shiboken2.dll`) are hard-linked into the build +folder of the application. diff --git a/examples/samplebinding/bindings.h b/examples/samplebinding/bindings.h new file mode 100644 index 000000000..ba42dc626 --- /dev/null +++ b/examples/samplebinding/bindings.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef BINDINGS_H +#define BINDINGS_H + +#include "icecream.h" +#include "truck.h" + +#endif // BINDINGS_H diff --git a/examples/samplebinding/bindings.xml b/examples/samplebinding/bindings.xml new file mode 100644 index 000000000..f08243694 --- /dev/null +++ b/examples/samplebinding/bindings.xml @@ -0,0 +1,80 @@ +<?xml version="1.0"?> +<!-- +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +--> +<typesystem package="Universe"> + + <primitive-type name="bool"/> + <primitive-type name="std::string"/> + + <object-type name="Icecream"> + <!-- By default the ownership of an object created in Python is tied + to the Python name pointing to it. In order for the underlying + C++ object not to get deleted when the Python name goes out of + scope, we have to transfer ownership to C++. + --> + <modify-function signature="clone()"> + <modify-argument index="0"> + <define-ownership owner="c++"/> + </modify-argument> + </modify-function> + </object-type> + + <value-type name="Truck"> + <!-- Same ownership caveat applies here. --> + <modify-function signature="addIcecreamFlavor(Icecream*)"> + <modify-argument index="1"> + <define-ownership owner="c++"/> + </modify-argument> + </modify-function> + </value-type> + +</typesystem> diff --git a/examples/samplebinding/icecream.cpp b/examples/samplebinding/icecream.cpp new file mode 100644 index 000000000..8d40302da --- /dev/null +++ b/examples/samplebinding/icecream.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "icecream.h" + +Icecream::Icecream(const std::string &flavor) : m_flavor(flavor) {} + +Icecream::~Icecream() {} + +const std::string Icecream::getFlavor() +{ + return m_flavor; +} + +Icecream *Icecream::clone() +{ + return new Icecream(*this); +} diff --git a/examples/samplebinding/icecream.h b/examples/samplebinding/icecream.h new file mode 100644 index 000000000..1997fdc49 --- /dev/null +++ b/examples/samplebinding/icecream.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ICECREAM_H +#define ICECREAM_H + +#include <string> + +#include "macros.h" + +class BINDINGS_API Icecream +{ +public: + Icecream(const std::string &flavor); + virtual Icecream *clone(); + virtual ~Icecream(); + virtual const std::string getFlavor(); + +private: + std::string m_flavor; +}; + + +#endif // ICECREAM_H diff --git a/examples/samplebinding/macros.h b/examples/samplebinding/macros.h new file mode 100644 index 000000000..71b27c398 --- /dev/null +++ b/examples/samplebinding/macros.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MACROS_H +#define MACROS_H + +#if defined _WIN32 || defined __CYGWIN__ + // Export symbols when creating .dll and .lib, and import them when using .lib. + #if BINDINGS_BUILD + #define BINDINGS_API __declspec(dllexport) + #else + #define BINDINGS_API __declspec(dllimport) + #endif + // Disable warnings about exporting STL types being a bad idea. Don't use this in production + // code. + #pragma warning( disable : 4251 ) +#else + #define BINDINGS_API +#endif + +#endif // MACROS_H diff --git a/examples/samplebinding/main.py b/examples/samplebinding/main.py new file mode 100644 index 000000000..b9487f7ba --- /dev/null +++ b/examples/samplebinding/main.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python + +############################################################################ +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +from __future__ import print_function + +"""An example showcasing how to use bindings for a custom non-Qt C++ library""" + +from Universe import Icecream, Truck + +class VanillaChocolateIcecream(Icecream): + def __init__(self, flavor=""): + super(VanillaChocolateIcecream, self).__init__(flavor) + + def clone(self): + return VanillaChocolateIcecream(self.getFlavor()) + + def getFlavor(self): + return "vanilla sprinked with chocolate" + +class VanillaChocolateCherryIcecream(VanillaChocolateIcecream): + def __init__(self, flavor=""): + super(VanillaChocolateIcecream, self).__init__(flavor) + + def clone(self): + return VanillaChocolateCherryIcecream(self.getFlavor()) + + def getFlavor(self): + base_flavor = super(VanillaChocolateCherryIcecream, self).getFlavor() + return base_flavor + " and a cherry" + +if __name__ == '__main__': + leave_on_destruction = True + truck = Truck(leave_on_destruction) + + flavors = ["vanilla", "chocolate", "strawberry"] + for f in flavors: + icecream = Icecream(f) + truck.addIcecreamFlavor(icecream) + + truck.addIcecreamFlavor(VanillaChocolateIcecream()) + truck.addIcecreamFlavor(VanillaChocolateCherryIcecream()) + + truck.arrive() + truck.printAvailableFlavors() + result = truck.deliver() + + if result: + print("All the kids got some icecream!") + else: + print("Aww, someone didn't get the flavor they wanted...") + + if not result: + special_truck = Truck(truck) + del truck + + print("") + special_truck.setArrivalMessage("A new SPECIAL icecream truck has arrived!\n") + special_truck.arrive() + special_truck.addIcecreamFlavor(Icecream("SPECIAL *magical* icecream")) + special_truck.printAvailableFlavors() + special_truck.deliver() + print("Now everyone got the flavor they wanted!") + special_truck.leave() diff --git a/examples/samplebinding/truck.cpp b/examples/samplebinding/truck.cpp new file mode 100644 index 000000000..6e24bdc87 --- /dev/null +++ b/examples/samplebinding/truck.cpp @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <iostream> +#include <random> + +#include "truck.h" + +Truck::Truck(bool leaveOnDestruction) : m_leaveOnDestruction(leaveOnDestruction) {} + +Truck::Truck(const Truck &other) +{ + for (size_t i = 0; i < other.m_flavors.size(); ++i) { + addIcecreamFlavor(other.m_flavors[i]->clone()); + } +} + +Truck &Truck::operator=(const Truck &other) +{ + if (this != &other) { + clearFlavors(); + for (size_t i = 0; i < other.m_flavors.size(); ++i) { + addIcecreamFlavor(other.m_flavors[i]->clone()); + } + } + return *this; +} + +Truck::~Truck() +{ + if (m_leaveOnDestruction) + leave(); + clearFlavors(); +} + +void Truck::addIcecreamFlavor(Icecream *icecream) +{ + m_flavors.push_back(icecream); +} + +void Truck::printAvailableFlavors() const +{ + std::cout << "It sells the following flavors: \n"; + for (size_t i = 0; i < m_flavors.size(); ++ i) { + std::cout << " * " << m_flavors[i]->getFlavor() << '\n'; + } + std::cout << '\n'; +} + +void Truck::arrive() const +{ + std::cout << m_arrivalMessage; +} + +void Truck::leave() const +{ + std::cout << "The truck left the neighborhood.\n"; +} + +void Truck::setLeaveOnDestruction(bool value) +{ + m_leaveOnDestruction = value; +} + +void Truck::setArrivalMessage(const std::string &message) +{ + m_arrivalMessage = message; +} + +bool Truck::deliver() const +{ + std::random_device rd; + std::mt19937 mt(rd()); + std::uniform_int_distribution<int> dist(1, 2); + + std::cout << "The truck started delivering icecream to all the kids in the neighborhood.\n"; + bool result = false; + + if (dist(mt) == 2) + result = true; + + return result; +} + +void Truck::clearFlavors() +{ + for (size_t i = 0; i < m_flavors.size(); ++i) { + delete m_flavors[i]; + } + m_flavors.clear(); +} diff --git a/examples/samplebinding/truck.h b/examples/samplebinding/truck.h new file mode 100644 index 000000000..02e304a82 --- /dev/null +++ b/examples/samplebinding/truck.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TRUCK_H +#define TRUCK_H + +#include <vector> + +#include "icecream.h" +#include "macros.h" + +class BINDINGS_API Truck { +public: + Truck(bool leaveOnDestruction = false); + Truck(const Truck &other); + Truck& operator=(const Truck &other); + ~Truck(); + + void addIcecreamFlavor(Icecream *icecream); + void printAvailableFlavors() const; + + bool deliver() const; + void arrive() const; + void leave() const; + + void setLeaveOnDestruction(bool value); + void setArrivalMessage(const std::string &message); + +private: + void clearFlavors(); + + bool m_leaveOnDestruction = false; + std::string m_arrivalMessage = "A new icecream truck has arrived!\n"; + std::vector<Icecream *> m_flavors; +}; + +#endif // TRUCK_H diff --git a/examples/scriptableapplication/CMakeLists.txt b/examples/scriptableapplication/CMakeLists.txt index 7e57a291b..4119b6756 100644 --- a/examples/scriptableapplication/CMakeLists.txt +++ b/examples/scriptableapplication/CMakeLists.txt @@ -23,7 +23,7 @@ macro(pyside2_config option output_var) endif() execute_process( - COMMAND python "${CMAKE_SOURCE_DIR}/pyside2_config.py" ${option} + COMMAND python "${CMAKE_SOURCE_DIR}/../utils/pyside2_config.py" ${option} OUTPUT_VARIABLE ${output_var} OUTPUT_STRIP_TRAILING_WHITESPACE) @@ -35,19 +35,19 @@ macro(pyside2_config option output_var) endif() endmacro() -# Get relevant general paths, include paths and linker flags. +# Query for the PySide2 path, Python path, include paths and linker flags. pyside2_config(--pyside2 PYSIDE2_PATH) +pyside2_config(--python-include PYTHON_INCLUDE_DIR) +pyside2_config(--pyside2-include PYSIDE2_INCLUDE_DIR 1) +pyside2_config(--pyside2-shared-libraries-cmake PYSIDE2_SHARED_LIBRARIES 0) +pyside2_config(--python-link-cmake PYTHON_LINKING_DATA 0) + set(SHIBOKEN_PATH "${PYSIDE2_PATH}/shiboken2${CMAKE_EXECUTABLE_SUFFIX}") if(NOT EXISTS ${SHIBOKEN_PATH}) message(FATAL_ERROR "Shiboken executable not found at path: ${SHIBOKEN_PATH}") endif() -pyside2_config(--pyside2 PYSIDE2_DIR) -pyside2_config(--python-include PYTHON_INCLUDE_DIR) -pyside2_config(--pyside2-include PYSIDE2_INCLUDE_DIR 1) -pyside2_config(--pyside2-shared-libraries-cmake PYSIDE2_SHARED_LIBRARIES 0) -pyside2_config(--python-link-cmake PYTHON_LINKING_DATA 0) # Get all relevant Qt include dirs, to pass them on to shiboken. get_property(QT_CORE_INCLUDE_DIRS TARGET Qt5::Core PROPERTY INTERFACE_INCLUDE_DIRECTORIES) @@ -122,7 +122,7 @@ endforeach() # Enable rpaths so that the example can be executed from the build dir. set(CMAKE_SKIP_BUILD_RPATH FALSE) set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) -set(CMAKE_INSTALL_RPATH ${PYSIDE2_DIR}) +set(CMAKE_INSTALL_RPATH ${PYSIDE2_PATH}) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) # ============================================================================================= # !!! End of dubious section. diff --git a/examples/scriptableapplication/pyside2.pri b/examples/scriptableapplication/pyside2.pri index 59f7fd983..17be4392f 100644 --- a/examples/scriptableapplication/pyside2.pri +++ b/examples/scriptableapplication/pyside2.pri @@ -1,19 +1,21 @@ -PYSIDE2 = $$system(python $$PWD/pyside2_config.py --pyside2) +PYSIDE_CONFIG = $$PWD/../utils/pyside2_config.py + +PYSIDE2 = $$system(python $$PYSIDE_CONFIG --pyside2) isEmpty(PYSIDE2): error(Unable to locate the PySide2 package location) -PYTHON_INCLUDE = $$system(python $$PWD/pyside2_config.py --python-include) +PYTHON_INCLUDE = $$system(python $$PYSIDE_CONFIG --python-include) isEmpty(PYTHON_INCLUDE): error(Unable to locate the Python include headers directory) -PYTHON_LFLAGS = $$system(python $$PWD/pyside2_config.py --python-link) +PYTHON_LFLAGS = $$system(python $$PYSIDE_CONFIG --python-link) isEmpty(PYTHON_LFLAGS): error(Unable to locate the Python library for linking) -PYSIDE2_INCLUDE = $$system(python $$PWD/pyside2_config.py --pyside2-include) +PYSIDE2_INCLUDE = $$system(python $$PYSIDE_CONFIG --pyside2-include) isEmpty(PYSIDE2_INCLUDE): error(Unable to locate the PySide2 include headers directory) -PYSIDE2_LFLAGS = $$system(python $$PWD/pyside2_config.py --pyside2-link) +PYSIDE2_LFLAGS = $$system(python $$PYSIDE_CONFIG --pyside2-link) isEmpty(PYSIDE2_LFLAGS): error(Unable to locate the PySide2 libraries for linking) -PYSIDE2_SHARED_LIBRARIES = $$system(python $$PWD/pyside2_config.py --pyside2-shared-libraries) +PYSIDE2_SHARED_LIBRARIES = $$system(python $$PYSIDE_CONFIG --pyside2-shared-libraries) isEmpty(PYSIDE2_SHARED_LIBRARIES): error(Unable to locate the used PySide2 shared libraries) INCLUDEPATH += "$$PYTHON_INCLUDE" $$PYSIDE2_INCLUDE diff --git a/examples/scriptableapplication/pyside2_config.py b/examples/utils/pyside2_config.py index ce9c707c1..298d40d5b 100644 --- a/examples/scriptableapplication/pyside2_config.py +++ b/examples/utils/pyside2_config.py @@ -72,10 +72,10 @@ def sharedLibraryGlobPattern(): glob = '*.' + sharedLibrarySuffix() return glob if sys.platform == 'win32' else 'lib' + glob -def filterPySide2SharedLibraries(list): +def filterPySide2SharedLibraries(list, only_shiboken=False): def predicate(item): basename = os.path.basename(item) - if 'shiboken' in basename or 'pyside2' in basename: + if 'shiboken' in basename or ('pyside2' in basename and not only_shiboken): return True return False result = [item for item in list if predicate(item)] @@ -165,11 +165,16 @@ def pythonLinkData(): return flags -def pyside2Include(): +def pyside2Include(only_shiboken=False): pySide2 = findPySide2() if pySide2 is None: return None - return "{0}/include/PySide2 {0}/include/shiboken2".format(pySide2) + + includes = "{0}/include/shiboken2".format(pySide2) + if not only_shiboken: + includes = includes + " {0}/include/PySide2".format(pySide2) + + return includes def pyside2Link(): pySide2 = findPySide2() @@ -182,13 +187,13 @@ def pyside2Link(): link += linkOption(lib) return link -def pyside2SharedLibrariesData(): +def pyside2SharedLibrariesData(only_shiboken=False): pySide2 = findPySide2() if pySide2 is None: return None glob_result = glob.glob(os.path.join(pySide2, sharedLibraryGlobPattern())) - filtered_libs = filterPySide2SharedLibraries(glob_result) + filtered_libs = filterPySide2SharedLibraries(glob_result, only_shiboken) libs = [] if sys.platform == 'win32': for lib in filtered_libs: @@ -218,8 +223,8 @@ def pyside2SharedLibraries(): libs_string += lib + ' ' return libs_string -def pyside2SharedLibrariesCmake(): - libs = pyside2SharedLibrariesData() +def pyside2SharedLibrariesCmake(only_shiboken=False): + libs = pyside2SharedLibrariesData(only_shiboken) result = ';'.join(libs) return result @@ -248,6 +253,12 @@ if option == '--pyside2-link' or option == '-a': print(l) +if option == '--shiboken-include' or option == '-a': + i = pyside2Include(only_shiboken=True) + if i is None: + sys.exit(pyside2_error) + print(i) + if option == '--pyside2-include' or option == '-a': i = pyside2Include() if i is None: @@ -283,3 +294,9 @@ if option == '--pyside2-shared-libraries-cmake' or option == '-a': if l is None: sys.exit(pyside2_libs_error) print(l) + +if option == '--shiboken-shared-libraries-cmake' or option == '-a': + l = pyside2SharedLibrariesCmake(only_shiboken=True) + if l is None: + sys.exit(pyside2_libs_error) + print(l) @@ -56,9 +56,10 @@ and --cmake=/path/to/bin/cmake respectively. -For windows, if OpenSSL support is required, it is necessary to specify -the directory with: - --openssl=/path/to/openssl/bin +For Windows, if OpenSSL support is required, it's necessary to specify +the directory path that contains the OpenSSL shared libraries +"libeay32.dll" and "ssleay32.dll", for example: + --openssl=C:\OpenSSL-Win64\bin ADDITIONAL OPTIONS: @@ -114,6 +115,11 @@ DEVELOPMENT OPTIONS: For development purposes the following options might be of use, when using `setup.py build`: + --module-subset allows for specifying the Qt modules to be built. + A minimal set is: --module-subset=Core,Gui,Test,Widgets + --skip-modules allows for specifying the Qt modules that will be + skipped during the build process. + For example: --skip-modules=WebEngineCore,WebEngineWidgets --reuse-build option allows recompiling only the modified sources and not the whole world, shortening development iteration time, --skip-cmake will reuse the already generated Makefiles (or @@ -145,8 +151,9 @@ OPTIONAL: Specifying the --openssl option is only required on Windows. It is a no-op for other platforms. - You can specify the location of OpenSSL DLLs with option: - --openssl=</path/to/openssl/bin>. + You can specify the location of the OpenSSL DLLs with the + following option: + --openssl=</path/to/openssl/bin-directory>. You can download OpenSSL for Windows here: http://slproweb.com/products/Win32OpenSSL.html (*) diff --git a/sources/pyside2/CMakeLists.txt b/sources/pyside2/CMakeLists.txt index 3e56881df..d4150c93b 100644 --- a/sources/pyside2/CMakeLists.txt +++ b/sources/pyside2/CMakeLists.txt @@ -17,8 +17,8 @@ if (USE_PYTHON_VERSION) find_package(PythonInterp ${USE_PYTHON_VERSION} REQUIRED) find_package(PythonLibs ${USE_PYTHON_VERSION} REQUIRED) else() - find_package(PythonInterp 2.6) - find_package(PythonLibs 2.6) + find_package(PythonInterp 2.7) + find_package(PythonLibs 2.7) endif() set(PYSIDE_VERSION_FILE_PATH "${CMAKE_SOURCE_DIR}/pyside_version.py") @@ -293,19 +293,20 @@ macro(COLLECT_MODULE_IF_FOUND shortname) endif() # If the module was found, and also the module path is the same as the - # Qt5Core base path, we will generate the list with the modules to be install + # Qt5Core base path, we will generate the list with the modules to be installed + set(looked_in_message ". Looked in: ${${_name_dir}}") if("${${_name_found}}" AND (("${found_basepath}" GREATER "0") OR ("${found_basepath}" EQUAL "0"))) - message(STATUS "${module_state} module ${name} found (${ARGN})") + message(STATUS "${module_state} module ${name} found (${ARGN})${looked_in_message}") # record the shortnames for the tests list(APPEND all_module_shortnames ${shortname}) else() if("${module_state}" STREQUAL "optional") - message(STATUS "optional module ${name} skipped") + message(STATUS "optional module ${name} skipped${looked_in_message}") elseif("${module_state}" STREQUAL "essential") message(STATUS "skipped module ${name} is essential!\n" - " We do not guarantee that all tests are working.") + " We do not guarantee that all tests are working.${looked_in_message}") else() - message(FATAL_ERROR "module ${name} MISSING") + message(FATAL_ERROR "module ${name} MISSING${looked_in_message}") endif() endif() endmacro() @@ -340,7 +341,10 @@ endif() if(WIN32) list(APPEND ALL_OPTIONAL_MODULES AxContainer) endif() -list(APPEND ALL_OPTIONAL_MODULES WebChannel WebEngineCore WebEngineWidgets WebKit WebKitWidgets WebSockets) +# Disabling WebKit by default +# If WebKit support is needed add the following elements +# to the list: WebKit WebKitWidgets +list(APPEND ALL_OPTIONAL_MODULES WebChannel WebEngineCore WebEngineWidgets WebSockets) if (Qt5Core_VERSION VERSION_GREATER 5.9.3) # Depending on fixes in Qt3D list(APPEND ALL_OPTIONAL_MODULES 3DCore 3DRender 3DInput 3DLogic 3DAnimation 3DExtras) endif() @@ -350,6 +354,14 @@ if (NOT MODULES) set(MODULES "${ALL_ESSENTIAL_MODULES};${ALL_OPTIONAL_MODULES}") endif() +# Removing from the MODULES list the items that were defined with +# -DSKIP_MODULES on command line +if (SKIP_MODULES) + foreach(s ${SKIP_MODULES}) + list(REMOVE_ITEM MODULES ${s}) + endforeach() +endif() + foreach(m ${MODULES}) COLLECT_MODULE_IF_FOUND(${m}) endforeach() diff --git a/sources/pyside2/PySide2/CMakeLists.txt b/sources/pyside2/PySide2/CMakeLists.txt index 651bf2734..c109b2e0e 100644 --- a/sources/pyside2/PySide2/CMakeLists.txt +++ b/sources/pyside2/PySide2/CMakeLists.txt @@ -10,7 +10,11 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/__init__.py.in" configure_file("${CMAKE_CURRENT_SOURCE_DIR}/_config.py.in" "${CMAKE_CURRENT_BINARY_DIR}/_config.py" @ONLY) -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/../pyside_version.py" +# Use absolute path instead of relative path, to avoid ninja build errors due to +# duplicate file dependency inconsistency. +set(pyside_version_relative_path "${CMAKE_CURRENT_SOURCE_DIR}/../pyside_version.py") +get_filename_component(pyside_version_path ${pyside_version_relative_path} ABSOLUTE) +configure_file("${pyside_version_path}" "${CMAKE_CURRENT_BINARY_DIR}/_git_pyside_version.py" @ONLY) # qt.conf needs to be placed next to QtWebEngineProcess so that the executable uses the correct diff --git a/sources/pyside2/PySide2/QtCore/CMakeLists.txt b/sources/pyside2/PySide2/QtCore/CMakeLists.txt index 5a8a41ec5..1d0b7d413 100644 --- a/sources/pyside2/PySide2/QtCore/CMakeLists.txt +++ b/sources/pyside2/PySide2/QtCore/CMakeLists.txt @@ -55,6 +55,7 @@ ${QtCore_GEN_DIR}/qfinalstate_wrapper.cpp ${QtCore_GEN_DIR}/qgenericargument_wrapper.cpp ${QtCore_GEN_DIR}/qgenericreturnargument_wrapper.cpp ${QtCore_GEN_DIR}/qhistorystate_wrapper.cpp +${QtCore_GEN_DIR}/qidentityproxymodel_wrapper.cpp ${QtCore_GEN_DIR}/qiodevice_wrapper.cpp ${QtCore_GEN_DIR}/qjsonarray_wrapper.cpp ${QtCore_GEN_DIR}/qjsondocument_wrapper.cpp @@ -67,8 +68,10 @@ ${QtCore_GEN_DIR}/qlibraryinfo_wrapper.cpp ${QtCore_GEN_DIR}/qline_wrapper.cpp ${QtCore_GEN_DIR}/qlinef_wrapper.cpp ${QtCore_GEN_DIR}/qlocale_wrapper.cpp +${QtCore_GEN_DIR}/qlockfile_wrapper.cpp ${QtCore_GEN_DIR}/qmargins_wrapper.cpp ${QtCore_GEN_DIR}/qmarginsf_wrapper.cpp +${QtCore_GEN_DIR}/qmessageauthenticationcode_wrapper.cpp ${QtCore_GEN_DIR}/qmessagelogcontext_wrapper.cpp ${QtCore_GEN_DIR}/qmetaclassinfo_wrapper.cpp ${QtCore_GEN_DIR}/qmetaenum_wrapper.cpp @@ -83,6 +86,7 @@ ${QtCore_GEN_DIR}/qmodelindex_wrapper.cpp ${QtCore_GEN_DIR}/qmutex_wrapper.cpp ${QtCore_GEN_DIR}/qmutexlocker_wrapper.cpp ${QtCore_GEN_DIR}/qobject_wrapper.cpp +${QtCore_GEN_DIR}/qoperatingsystemversion_wrapper.cpp ${QtCore_GEN_DIR}/qparallelanimationgroup_wrapper.cpp ${QtCore_GEN_DIR}/qpauseanimation_wrapper.cpp ${QtCore_GEN_DIR}/qpersistentmodelindex_wrapper.cpp @@ -109,6 +113,7 @@ ${QtCore_GEN_DIR}/qsemaphore_wrapper.cpp ${QtCore_GEN_DIR}/qsemaphorereleaser_wrapper.cpp ${QtCore_GEN_DIR}/qsequentialanimationgroup_wrapper.cpp ${QtCore_GEN_DIR}/qsettings_wrapper.cpp +${QtCore_GEN_DIR}/qsignalblocker_wrapper.cpp ${QtCore_GEN_DIR}/qsignalmapper_wrapper.cpp ${QtCore_GEN_DIR}/qsignaltransition_wrapper.cpp ${QtCore_GEN_DIR}/qsize_wrapper.cpp diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml index 77d074077..994bc10c8 100644 --- a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml +++ b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml @@ -1976,6 +1976,11 @@ </inject-code> </add-function> </value-type> + <object-type name="QLockFile"> + <enum-type name="LockError"/> + </object-type> + <object-type name="QMessageAuthenticationCode"/> + <object-type name="QSignalBlocker"/> <value-type name="QStorageInfo"/> <!-- QReadWriteLock does not have a copy ctor! --> <object-type name="QReadWriteLock"> @@ -2126,6 +2131,7 @@ <modify-function signature="filterChanged()" remove="all"/> <!--### End of obsolete section --> </object-type> + <object-type name="QIdentityProxyModel"/> <!-- QObject is created manually --> <object-type name="QObject"> <extra-includes> @@ -2957,6 +2963,9 @@ </inject-code> </modify-function> </object-type> + <value-type name="QOperatingSystemVersion" since="5.9"> + <enum-type name="OSType"/> + </value-type> <object-type name="QLibraryInfo"> <enum-type name="LibraryLocation"/> </object-type> @@ -3006,27 +3015,27 @@ <object-type name="QSocketNotifier"> <enum-type name="Type"/> - <add-function signature="QSocketNotifier(PyObject*,QSocketNotifier::Type,QObject*)"> - <modify-argument index="3"> - <replace-default-expression with="0" /> - <rename to="parent" /> - </modify-argument> - <inject-code> - Shiboken::AutoDecRef fileNo(PyObject_GetAttrString(%PYARG_1, "fileno")); - if (!fileNo.isNull()) { - Shiboken::AutoDecRef fileNoValue(PyObject_CallObject(fileNo, 0)); - if (%CHECKTYPE[int](fileNoValue)) { - int cppFileNoValue = %CONVERTTOCPP[int](fileNoValue); - /* Qt4 version: - * %0 = new %TYPE(cppFileNoValue, %2, %3); - * Qt5 has qintptr instead. - * XXX check if this means a pointer or just the pointer size cast (what I implemented) - */ - qintptr socket = (qintptr)cppFileNoValue; - %0 = new %TYPE(socket, %2, %3); - } - } - </inject-code> + <add-function signature="QSocketNotifier(PyObject*, QSocketNotifier::Type, QObject*)"> + <modify-argument index="3"> + <replace-default-expression with="0" /> + <rename to="parent" /> + </modify-argument> + <inject-code> + Shiboken::AutoDecRef socket(%PYARG_1); + if (!socket.isNull()) { + // We use qintptr as PyLong, but we check for int + // since it is currently an alias to be Python2 compatible. + // Internally, ints are qlonglongs. + if (%CHECKTYPE[int](socket)) { + int cppSocket = %CONVERTTOCPP[int](socket); + qintptr socket = (qintptr)cppSocket; + %0 = new %TYPE(socket, %2, %3); + } else { + PyErr_SetString(PyExc_TypeError, + "QSocketNotifier: first argument (socket) must be an int."); + } + } + </inject-code> </add-function> </object-type> @@ -3262,6 +3271,14 @@ QCoreApplicationConstructor(%PYSELF, args, &%0); </inject-code> </add-function> + <add-function signature="QCoreApplication()"> + <inject-code> + PyObject *empty = PyTuple_New(2); + if (!PyTuple_SetItem(empty, 0, PyList_New(0))) { + QCoreApplicationConstructor(%PYSELF, empty, &%0); + } + </inject-code> + </add-function> <!-- blocking functions --> <modify-function signature="processEvents(QFlags<QEventLoop::ProcessEventsFlag>,int)" allow-thread="yes"/> <modify-function signature="processEvents(QFlags<QEventLoop::ProcessEventsFlag>)" allow-thread="yes"/> diff --git a/sources/pyside2/PySide2/QtGui/CMakeLists.txt b/sources/pyside2/PySide2/QtGui/CMakeLists.txt index 807f9b31e..bee58bde2 100644 --- a/sources/pyside2/PySide2/QtGui/CMakeLists.txt +++ b/sources/pyside2/PySide2/QtGui/CMakeLists.txt @@ -7,7 +7,21 @@ ${QtGui_GEN_DIR}/qabstractopenglfunctions_wrapper.cpp ${QtGui_GEN_DIR}/qabstracttextdocumentlayout_paintcontext_wrapper.cpp ${QtGui_GEN_DIR}/qabstracttextdocumentlayout_selection_wrapper.cpp ${QtGui_GEN_DIR}/qabstracttextdocumentlayout_wrapper.cpp +${QtGui_GEN_DIR}/qaccessible_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibleeditabletextinterface_wrapper.cpp ${QtGui_GEN_DIR}/qaccessibleevent_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibleobject_wrapper.cpp +${QtGui_GEN_DIR}/qaccessiblestatechangeevent_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibletablecellinterface_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibletablemodelchangeevent_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibletextcursorevent_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibletextinsertevent_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibletextinterface_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibletextremoveevent_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibletextselectionevent_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibletextupdateevent_wrapper.cpp +${QtGui_GEN_DIR}/qaccessiblevaluechangeevent_wrapper.cpp +${QtGui_GEN_DIR}/qaccessiblevalueinterface_wrapper.cpp ${QtGui_GEN_DIR}/qactionevent_wrapper.cpp ${QtGui_GEN_DIR}/qbackingstore_wrapper.cpp ${QtGui_GEN_DIR}/qbitmap_wrapper.cpp @@ -48,8 +62,10 @@ ${QtGui_GEN_DIR}/qimageiohandler_wrapper.cpp ${QtGui_GEN_DIR}/qimagereader_wrapper.cpp ${QtGui_GEN_DIR}/qimagewriter_wrapper.cpp ${QtGui_GEN_DIR}/qinputevent_wrapper.cpp +${QtGui_GEN_DIR}/qinputmethod_wrapper.cpp ${QtGui_GEN_DIR}/qinputmethodevent_attribute_wrapper.cpp ${QtGui_GEN_DIR}/qinputmethodevent_wrapper.cpp +${QtGui_GEN_DIR}/qinputmethodqueryevent_wrapper.cpp ${QtGui_GEN_DIR}/qintvalidator_wrapper.cpp ${QtGui_GEN_DIR}/qkeyevent_wrapper.cpp ${QtGui_GEN_DIR}/qkeysequence_wrapper.cpp @@ -67,6 +83,7 @@ ${QtGui_GEN_DIR}/qmatrix4x4_wrapper.cpp ${QtGui_GEN_DIR}/qmouseevent_wrapper.cpp ${QtGui_GEN_DIR}/qmoveevent_wrapper.cpp ${QtGui_GEN_DIR}/qmovie_wrapper.cpp +${QtGui_GEN_DIR}/qnativegestureevent_wrapper.cpp ${QtGui_GEN_DIR}/qoffscreensurface_wrapper.cpp ${QtGui_GEN_DIR}/qopenglcontextgroup_wrapper.cpp ${QtGui_GEN_DIR}/qopengldebuglogger_wrapper.cpp @@ -78,6 +95,7 @@ ${QtGui_GEN_DIR}/qopenglfunctions_wrapper.cpp ${QtGui_GEN_DIR}/qopenglpixeltransferoptions_wrapper.cpp ${QtGui_GEN_DIR}/qopenglshaderprogram_wrapper.cpp ${QtGui_GEN_DIR}/qopengltexture_wrapper.cpp +${QtGui_GEN_DIR}/qopengltextureblitter_wrapper.cpp ${QtGui_GEN_DIR}/qopengltimemonitor_wrapper.cpp ${QtGui_GEN_DIR}/qopengltimerquery_wrapper.cpp ${QtGui_GEN_DIR}/qopenglversionprofile_wrapper.cpp @@ -107,6 +125,7 @@ ${QtGui_GEN_DIR}/qpixmap_wrapper.cpp ${QtGui_GEN_DIR}/qpixmapcache_key_wrapper.cpp ${QtGui_GEN_DIR}/qpixmapcache_wrapper.cpp ${QtGui_GEN_DIR}/qpixelformat_wrapper.cpp +${QtGui_GEN_DIR}/qpointingdeviceuniqueid_wrapper.cpp ${QtGui_GEN_DIR}/qpolygon_wrapper.cpp ${QtGui_GEN_DIR}/qpolygonf_wrapper.cpp ${QtGui_GEN_DIR}/qpytextobject_wrapper.cpp @@ -123,7 +142,6 @@ ${QtGui_GEN_DIR}/qstandarditemmodel_wrapper.cpp ${QtGui_GEN_DIR}/qstatustipevent_wrapper.cpp ${QtGui_GEN_DIR}/qopenglbuffer_wrapper.cpp ${QtGui_GEN_DIR}/qopenglcontext_wrapper.cpp -${QtGui_GEN_DIR}/qaccessible_wrapper.cpp ${QtGui_GEN_DIR}/qaccessible_state_wrapper.cpp ${QtGui_GEN_DIR}/qaccessibleinterface_wrapper.cpp ${QtGui_GEN_DIR}/qscreen_wrapper.cpp @@ -132,6 +150,8 @@ ${QtGui_GEN_DIR}/qopenglshader_wrapper.cpp ${QtGui_GEN_DIR}/qopenglframebufferobject_wrapper.cpp ${QtGui_GEN_DIR}/qrasterwindow_wrapper.cpp ${QtGui_GEN_DIR}/qrawfont_wrapper.cpp +${QtGui_GEN_DIR}/qscrollevent_wrapper.cpp +${QtGui_GEN_DIR}/qscrollprepareevent_wrapper.cpp ${QtGui_GEN_DIR}/qstatictext_wrapper.cpp ${QtGui_GEN_DIR}/qstylehints_wrapper.cpp ${QtGui_GEN_DIR}/qsurface_wrapper.cpp diff --git a/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml b/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml index 903260200..47bf62992 100644 --- a/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml +++ b/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml @@ -119,7 +119,7 @@ besides the fact they are accessible by ordinary event methods. --> - <rejection class="QAccessibleEvent" field-name="m_type"/> + <rejection class="^QAccessible.*Event$" field-name="^m_.*$"/> <rejection class="QEnterEvent" field-name="l"/> <rejection class="QEnterEvent" field-name="w"/> @@ -132,6 +132,7 @@ <rejection class="QMouseEvent" field-name="g"/> <rejection class="QMouseEvent" field-name="b"/> <rejection class="QMouseEvent" field-name="mouseState"/> + <rejection class="QNativeGestureEvent" field-name="^m.*$"/> <rejection class="QHoverEvent" field-name="p"/> <rejection class="QHoverEvent" field-name="op"/> @@ -222,6 +223,35 @@ </conversion-rule> </primitive-type> + <value-type name="QAccessible"> + <value-type name="State"/> + <enum-type name="Event"/> + <enum-type name="Role"/> + <enum-type name="Text"/> + <enum-type name="RelationFlag" flags="Relation"/> + <enum-type name="InterfaceType"/> + <enum-type name="TextBoundaryType"/> + </value-type> + + <object-type name="QAccessibleEditableTextInterface"/> + <object-type name="QAccessibleInterface"/> + <object-type name="QAccessibleObject"/> + <object-type name="QAccessibleTableCellInterface"/> + <object-type name="QAccessibleTextInterface"/> + <object-type name="QAccessibleValueInterface"/> + + <object-type name="QAccessibleEvent" copyable="false" polymorphic-id-expression="%1->type() == QAccessible::InvalidEvent"/> + <object-type name="QAccessibleStateChangeEvent" copyable="false" polymorphic-id-expression="%1->type() == QAccessible::StateChanged"/> + <object-type name="QAccessibleTableModelChangeEvent" copyable="false" polymorphic-id-expression="%1->type() == QAccessible::TableModelChanged"> + <enum-type name="ModelChangeType"/> + </object-type> + <object-type name="QAccessibleTextCursorEvent" copyable="false" polymorphic-id-expression="%1->type() == QAccessible::TextCaretMoved"/> + <object-type name="QAccessibleTextInsertEvent" copyable="false" polymorphic-id-expression="%1->type() == QAccessible::TextInserted"/> + <object-type name="QAccessibleTextRemoveEvent" copyable="false" polymorphic-id-expression="%1->type() == QAccessible::TextRemoved"/> + <object-type name="QAccessibleTextSelectionEvent" copyable="false" polymorphic-id-expression="%1->type() == QAccessible::TextSelectionChanged"/> + <object-type name="QAccessibleTextUpdateEvent" copyable="false" polymorphic-id-expression="%1->type() == QAccessible::TextUpdated"/> + <object-type name="QAccessibleValueChangeEvent" copyable="false" polymorphic-id-expression="%1->type() == QAccessible::ValueChanged"/> + <value-type name="QTransform"> <enum-type name="TransformationType"/> <add-function signature="__repr__" return-type="PyObject*"> @@ -383,6 +413,9 @@ <enum-type name="ColorGroup" /> <enum-type name="ColorRole" /> </value-type> + <object-type name="QInputMethod"> + <enum-type name="Action" /> + </object-type> <value-type name="QKeySequence"> <enum-type name="SequenceFormat"/> <enum-type name="SequenceMatch"/> @@ -1782,8 +1815,10 @@ </value-type> <!-- endif ndef QT_NO_INPUTMETHOD --> </object-type> + <object-type name="QInputMethodQueryEvent" copyable="false" polymorphic-id-expression="%1->type() == QEvent::InputMethodQuery"/> <object-type name="QMoveEvent" copyable = "false" polymorphic-id-expression="%1->type() == QEvent::Move" /> + <object-type name="QNativeGestureEvent" copyable="false" polymorphic-id-expression="%1->type() == QEvent::NativeGesture"/> <object-type name="QResizeEvent" copyable = "false" polymorphic-id-expression="%1->type() == QEvent::Resize"/> <object-type name="QShortcutEvent" copyable = "false" polymorphic-id-expression="%1->type() == QEvent::Shortcut"> </object-type> @@ -1813,7 +1848,10 @@ </object-type> <object-type name="QMouseEvent" copyable= "false" polymorphic-id-expression="%1->type() == QEvent::MouseButtonDblClick || %1->type() == QEvent::MouseButtonPress || %1->type() == QEvent::MouseButtonRelease || %1->type() == QEvent::MouseMove"/> <object-type name="QPaintEvent" copyable= "false" polymorphic-id-expression="%1->type() == QEvent::Paint"/> - <object-type name="QAccessibleEvent" polymorphic-id-expression="%1->type() == QEvent::AccessibilityDescription || %1->type() == QEvent::AccessibilityHelp"/> + <object-type name="QScrollEvent" copyable="false" polymorphic-id-expression="%1->type() == QEvent::Scroll"> + <enum-type name="ScrollState"/> + </object-type> + <object-type name="QScrollPrepareEvent" copyable="false" polymorphic-id-expression="%1->type() == QEvent::ScrollPrepare"/> <object-type name="QTextFrame" > <extra-includes> @@ -3056,7 +3094,6 @@ _______ end of matrix block _______ --> - <value-type name="QQuaternion" since="4.6"> <add-function signature="__repr__" return-type="PyObject*"> <inject-code class="target" position="beginning"> @@ -3251,22 +3288,19 @@ QGuiApplicationConstructor(%PYSELF, args, &%0); </inject-code> </add-function> + <add-function signature="QGuiApplication()"> + <inject-code> + PyObject *empty = PyTuple_New(2); + if (!PyTuple_SetItem(empty, 0, PyList_New(0))) { + QGuiApplicationConstructor(%PYSELF, empty, &%0); + } + </inject-code> + </add-function> <modify-function signature="exec()" rename="exec_" allow-thread="yes"/> <inject-code class="native" file="glue/qguiapplication_init.cpp" position="beginning" /> </object-type> - <value-type name="QAccessible"> - <value-type name="State"/> - <enum-type name="Role"/> - <enum-type name="Text"/> - <enum-type name="RelationFlag"/> - <enum-type name="InterfaceType"/> - <enum-type name="TextBoundaryType"/> - <enum-type name="Event"/> - </value-type> - <object-type name="QAccessibleInterface"> - </object-type> <object-type name="QOpenGLBuffer" since="5.0"> <enum-type name="Access" /> <enum-type name="RangeAccessFlag" flags="RangeAccessFlags" /> @@ -3661,6 +3695,7 @@ <modify-function signature="borderColor(int*)const" remove="all"/> <modify-function signature="borderColor(float*)const" remove="all"/> </object-type> + <object-type name="QOpenGLTextureBlitter"/> <object-type name="QOpenGLTimeMonitor" since="5.1"/> <object-type name="QOpenGLTimerQuery" since="5.1"/> <object-type name="QOpenGLWindow" since="5.4"> @@ -3691,6 +3726,7 @@ <enum-type name="YUVLayout"/> </value-type> <object-type name="QPdfWriter"/> + <value-type name="QPointingDeviceUniqueId"/> <value-type name="QRawFont"> <enum-type name="AntialiasingType"/> <enum-type name="LayoutFlag" flags="LayoutFlags"/> diff --git a/sources/pyside2/PySide2/QtMultimedia/CMakeLists.txt b/sources/pyside2/PySide2/QtMultimedia/CMakeLists.txt index 030426b05..e9caaa64b 100644 --- a/sources/pyside2/PySide2/QtMultimedia/CMakeLists.txt +++ b/sources/pyside2/PySide2/QtMultimedia/CMakeLists.txt @@ -27,7 +27,10 @@ ${QtMultimedia_GEN_DIR}/qcameracapturedestinationcontrol_wrapper.cpp ${QtMultimedia_GEN_DIR}/qcameracontrol_wrapper.cpp ${QtMultimedia_GEN_DIR}/qcameraexposurecontrol_wrapper.cpp # Private destructor: ${QtMultimedia_GEN_DIR}/qcameraexposure_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcamerafeedbackcontrol_wrapper.cpp # Private destructor: ${${QtMultimedia_GEN_DIR}/qcamerafocus_wrapper.cpp +# needs enums from QCameraFocus ${QtMultimedia_GEN_DIR}/qcameraflashcontrol_wrapper.cpp +# needs enums from QCameraFocus ${QtMultimedia_GEN_DIR}/qcamerafocuscontrol_wrapper.cpp ${QtMultimedia_GEN_DIR}/qcamerafocuszone_wrapper.cpp ${QtMultimedia_GEN_DIR}/qcamera_frameraterange_wrapper.cpp ${QtMultimedia_GEN_DIR}/qcameraimagecapturecontrol_wrapper.cpp @@ -60,7 +63,19 @@ ${QtMultimedia_GEN_DIR}/qmediaplaylist_wrapper.cpp ${QtMultimedia_GEN_DIR}/qmediarecordercontrol_wrapper.cpp ${QtMultimedia_GEN_DIR}/qmediarecorder_wrapper.cpp ${QtMultimedia_GEN_DIR}/qmediaresource_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaservice_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaservicecamerainfointerface_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaservicedefaultdeviceinterface_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaservicefeaturesinterface_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaserviceproviderhint_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaservicesupporteddevicesinterface_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaservicesupportedformatsinterface_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediastreamscontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediatimeinterval_wrapper.cpp ${QtMultimedia_GEN_DIR}/qmediatimerange_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediavideoprobecontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmetadatareadercontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmetadatawritercontrol_wrapper.cpp ${QtMultimedia_GEN_DIR}/qmultimedia_wrapper.cpp ${QtMultimedia_GEN_DIR}/qradiodatacontrol_wrapper.cpp ${QtMultimedia_GEN_DIR}/qradiodata_wrapper.cpp diff --git a/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_common.xml b/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_common.xml index fb353c7a1..5486fb157 100644 --- a/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_common.xml +++ b/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_common.xml @@ -217,6 +217,9 @@ <enum-type name="ExposureParameter"/> <modify-function signature="supportedParameterRange(QCameraExposureControl::ExposureParameter,bool*)const" remove="all"/> </object-type> + <object-type name="QCameraFeedbackControl"> + <enum-type name="EventType"/> + </object-type> <value-type name="QCameraFocusZone"> <enum-type name="FocusZoneStatus"/> </value-type> @@ -225,6 +228,8 @@ <enum-type name="FocusMode" flags="FocusModes"/> <enum-type name="FocusPointMode"/> </object-type> + <object-type name="QCameraFlashControl"/> needs enums from QCameraFocus + <object-type name="QCameraFocusControl"/> --> <value-type name="QCameraInfo"/> <object-type name="QCameraInfoControl"/> @@ -313,7 +318,25 @@ </object-type> <object-type name="QMediaRecorderControl"/> <value-type name="QMediaResource"/> + <object-type name="QMediaService"/> + <interface-type name="QMediaServiceCameraInfoInterface"/> + <interface-type name="QMediaServiceDefaultDeviceInterface"/> + <interface-type name="QMediaServiceFeaturesInterface"/> + <value-type name="QMediaServiceProviderHint"> + <enum-type name="Type"/> + <enum-type name="Feature" flags="Features"/> + </value-type> + <interface-type name="QMediaServiceSupportedDevicesInterface"/> + <interface-type name="QMediaServiceSupportedFormatsInterface"/> + <object-type name="QMediaStreamsControl"> + <enum-type name="StreamType"/> + </object-type> + <value-type name="QMediaTimeInterval"/> <value-type name="QMediaTimeRange"/> + <object-type name="QMediaVideoProbeControl"/> + + <object-type name="QMetaDataReaderControl"/> + <object-type name="QMetaDataWriterControl"/> <namespace-type name="QMultimedia"> <enum-type name="SupportEstimate"/> diff --git a/sources/pyside2/PySide2/QtWidgets/CMakeLists.txt b/sources/pyside2/PySide2/QtWidgets/CMakeLists.txt index 27dff2912..dee79744f 100644 --- a/sources/pyside2/PySide2/QtWidgets/CMakeLists.txt +++ b/sources/pyside2/PySide2/QtWidgets/CMakeLists.txt @@ -8,6 +8,7 @@ check_qt_class(QtWidgets QGtkStyle QtWidgets_OPTIONAL_SRC QtWid check_qt_class(QtWidgets QMacStyle QtWidgets_OPTIONAL_SRC QtWidgets_DROPPED_ENTRIES) set(QtWidgets_SRC +${QtWidgets_GEN_DIR}/qaccessiblewidget_wrapper.cpp ${QtWidgets_GEN_DIR}/qabstractbutton_wrapper.cpp ${QtWidgets_GEN_DIR}/qabstractgraphicsshapeitem_wrapper.cpp ${QtWidgets_GEN_DIR}/qabstractitemdelegate_wrapper.cpp @@ -122,11 +123,14 @@ ${QtWidgets_GEN_DIR}/qplaintextdocumentlayout_wrapper.cpp ${QtWidgets_GEN_DIR}/qplaintextedit_wrapper.cpp ${QtWidgets_GEN_DIR}/qprogressbar_wrapper.cpp ${QtWidgets_GEN_DIR}/qprogressdialog_wrapper.cpp +${QtWidgets_GEN_DIR}/qproxystyle_wrapper.cpp ${QtWidgets_GEN_DIR}/qpushbutton_wrapper.cpp ${QtWidgets_GEN_DIR}/qradiobutton_wrapper.cpp ${QtWidgets_GEN_DIR}/qrubberband_wrapper.cpp ${QtWidgets_GEN_DIR}/qscrollarea_wrapper.cpp ${QtWidgets_GEN_DIR}/qscrollbar_wrapper.cpp +${QtWidgets_GEN_DIR}/qscroller_wrapper.cpp +${QtWidgets_GEN_DIR}/qscrollerproperties_wrapper.cpp ${QtWidgets_GEN_DIR}/qshortcut_wrapper.cpp ${QtWidgets_GEN_DIR}/qsizegrip_wrapper.cpp ${QtWidgets_GEN_DIR}/qsizepolicy_wrapper.cpp diff --git a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml index feb3882ff..b4a6c2453 100644 --- a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml +++ b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml @@ -190,6 +190,7 @@ <enum-type name="ViewItemPosition"/> </value-type> + <object-type name="QAccessibleWidget"/> <value-type name="QColormap"> <enum-type name="Mode"/> </value-type> @@ -996,6 +997,13 @@ <object-type name="QProgressBar"> <enum-type name="Direction"/> </object-type> + <object-type name="QProxyStyle"> + <modify-function signature="QProxyStyle(QStyle*)"> + <modify-argument index="1"> + <define-ownership owner="c++"/> + </modify-argument> + </modify-function> + </object-type> <object-type name="QPushButton" /> <object-type name="QScrollArea"> <modify-function signature="setWidget(QWidget*)"> @@ -3193,6 +3201,14 @@ QApplicationConstructor(%PYSELF, args, &%0); </inject-code> </add-function> + <add-function signature="QApplication()"> + <inject-code> + PyObject *empty = PyTuple_New(2); + if (!PyTuple_SetItem(empty, 0, PyList_New(0))) { + QApplicationConstructor(%PYSELF, empty, &%0); + } + </inject-code> + </add-function> <modify-function signature="exec()" rename="exec_" allow-thread="yes"/> <inject-code class="native" file="glue/qapplication_init.cpp" position="beginning" /> </object-type> @@ -3665,6 +3681,17 @@ <value-type name="QTileRules" since="4.6"/> + <object-type name="QScroller"> + <enum-type name="State"/> + <enum-type name="ScrollerGestureType"/> + <enum-type name="Input"/> + </object-type> + <value-type name="QScrollerProperties"> + <enum-type name="OvershootPolicy"/> + <enum-type name="FrameRates"/> + <enum-type name="ScrollMetric"/> + </value-type> + <object-type name="QSizeGrip"/> <object-type name="QSystemTrayIcon"> diff --git a/sources/pyside2/doc/_templates/layout.html b/sources/pyside2/doc/_templates/layout.html index 561bed8ee..6ab1276a3 100644 --- a/sources/pyside2/doc/_templates/layout.html +++ b/sources/pyside2/doc/_templates/layout.html @@ -8,7 +8,7 @@ <div id="container"> <div class="header"> <div class="header_container"> - <div class="logo"><a href="http://www.pyside.org"><img alt="PySide" src="{{ pathto('_static/pysidelogo.png', 1) }}" width="199" height="102" /></a></div> + <div class="logo"><a href="http://www.pyside.org"><img alt="PySide" src="{{ pathto('_static/pysidelogo.png', 1) }}"/></a></div> <div class="related"> <ul> {%- block rootrellink %} diff --git a/sources/pyside2/doc/_themes/pysidedocs/static/pysidelogo.png b/sources/pyside2/doc/_themes/pysidedocs/static/pysidelogo.png Binary files differindex 076c1057c..882a004dd 100644 --- a/sources/pyside2/doc/_themes/pysidedocs/static/pysidelogo.png +++ b/sources/pyside2/doc/_themes/pysidedocs/static/pysidelogo.png diff --git a/sources/pyside2/doc/additionaldocs.lst b/sources/pyside2/doc/additionaldocs.lst index ff03d3656..037cb60f7 100644 --- a/sources/pyside2/doc/additionaldocs.lst +++ b/sources/pyside2/doc/additionaldocs.lst @@ -50,7 +50,9 @@ # fi # fi # done +# A line enclosed in [] denotes a (relative) target directory +[overviews] animation-overview.webxml animation.webxml application-windows.webxml diff --git a/sources/pyside2/doc/conf.py.in b/sources/pyside2/doc/conf.py.in index 10c0af5f3..e5fc80fb7 100644 --- a/sources/pyside2/doc/conf.py.in +++ b/sources/pyside2/doc/conf.py.in @@ -23,7 +23,10 @@ sys.path.append('@pyside_BINARY_DIR@') # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.todo', 'sphinx.ext.graphviz', 'inheritance_diagram', 'pysideinclude'] +#extensions = ['sphinx.ext.todo', 'sphinx.ext.graphviz', 'inheritance_diagram', 'pysideinclude'] +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.ifconfig', +'sphinx.ext.coverage', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', +'sphinx.ext.graphviz', 'inheritance_diagram', 'pysideinclude'] rst_epilog = """ .. |project| replace:: Qt for Python @@ -161,3 +164,7 @@ html_show_sourcelink = False # Output file base name for HTML help builder. #htmlhelp_basename = 'PySideDoc' + +# Link to the shiboken2 sphinx project to enable linking +# between the two projects. +intersphinx_mapping = {'shiboken2': ('@CMAKE_BINARY_DIR@/../shiboken2/doc/html','@CMAKE_BINARY_DIR@/../shiboken2/doc/html/objects.inv')} diff --git a/sources/pyside2/doc/contents.rst b/sources/pyside2/doc/contents.rst index f6e2f6abd..d31305889 100644 --- a/sources/pyside2/doc/contents.rst +++ b/sources/pyside2/doc/contents.rst @@ -6,24 +6,10 @@ gettingstarted.rst modules.rst - licenses.rst - -Tutorials -========= - -.. toctree:: - :maxdepth: 2 - tutorials/index.rst - -Other stuff -=========== - -.. toctree:: - :maxdepth: 1 - pysideapi2.rst pysideversion.rst + licenses.rst Module Index ============ diff --git a/sources/pyside2/doc/index.rst b/sources/pyside2/doc/index.rst index 90c95ade9..26bfe998f 100644 --- a/sources/pyside2/doc/index.rst +++ b/sources/pyside2/doc/index.rst @@ -96,7 +96,9 @@ Qt Modules Provides access to sensor hardware via QML and Python interfaces and a motion gesture recognition API for devices. - -provides access to sensor hardware via QML and C++ interfaces. The Qt Sensors API also provides a motion gesture recognition API for devices. +|project| also comes with the +:doc:`Shiboken2 <shiboken2:contents>` generator that outputs C++ code +for CPython extensions. .. toctree:: :maxdepth: 2 diff --git a/sources/pyside2/tests/QtCore/CMakeLists.txt b/sources/pyside2/tests/QtCore/CMakeLists.txt index 3a08cb45b..dc7aa3ddd 100644 --- a/sources/pyside2/tests/QtCore/CMakeLists.txt +++ b/sources/pyside2/tests/QtCore/CMakeLists.txt @@ -53,6 +53,7 @@ PYSIDE_TEST(qbytearray_test.py) PYSIDE_TEST(qcollator_test.py) PYSIDE_TEST(qcommandlineparser_test.py) PYSIDE_TEST(qcoreapplication_instance_test.py) +PYSIDE_TEST(qcoreapplication_test.py) PYSIDE_TEST(qdatastream_test.py) PYSIDE_TEST(qdatetime_test.py) PYSIDE_TEST(qdate_test.py) @@ -66,6 +67,8 @@ PYSIDE_TEST(qflags_test.py) PYSIDE_TEST(qinstallmsghandler_test.py) PYSIDE_TEST(qlinef_test.py) PYSIDE_TEST(qlocale_test.py) +PYSIDE_TEST(qlockfile_test.py) +PYSIDE_TEST(qmessageauthenticationcode_test.py) PYSIDE_TEST(qmetaobject_test.py) PYSIDE_TEST(qmimedatabase_test.py) PYSIDE_TEST(qmodelindex_internalpointer_test.py) @@ -81,6 +84,7 @@ PYSIDE_TEST(qobject_protected_methods_test.py) PYSIDE_TEST(qobject_test.py) PYSIDE_TEST(qobject_timer_event_test.py) PYSIDE_TEST(qobject_tr_as_instance_test.py) +PYSIDE_TEST(qoperatingsystemversion_test.py) PYSIDE_TEST(qpoint_test.py) PYSIDE_TEST(qprocess_test.py) PYSIDE_TEST(qproperty_decorator.py) @@ -90,6 +94,7 @@ PYSIDE_TEST(qregularexpression_test.py) PYSIDE_TEST(qresource_test.py) PYSIDE_TEST(qsize_test.py) PYSIDE_TEST(qslot_object_test.py) +PYSIDE_TEST(qsocketnotifier_test.py) PYSIDE_TEST(qsrand_test.py) PYSIDE_TEST(qstandardpaths_test.py) PYSIDE_TEST(qstatemachine_test.py) diff --git a/sources/pyside2/tests/QtCore/blocking_signals_test.py b/sources/pyside2/tests/QtCore/blocking_signals_test.py index 769820355..2f8b95b27 100644 --- a/sources/pyside2/tests/QtCore/blocking_signals_test.py +++ b/sources/pyside2/tests/QtCore/blocking_signals_test.py @@ -32,7 +32,7 @@ import unittest import os from tempfile import mkstemp -from PySide2.QtCore import QObject, SIGNAL, QFile +from PySide2.QtCore import QObject, SIGNAL, QFile, QSignalBlocker class TestSignalsBlockedBasic(unittest.TestCase): '''Basic test case for signalsBlocked''' @@ -46,6 +46,15 @@ class TestSignalsBlockedBasic(unittest.TestCase): self.assertTrue(not obj.blockSignals(True)) self.assertTrue(obj.signalsBlocked()) self.assertTrue(obj.blockSignals(False)) + blocker = QSignalBlocker(obj) + self.assertTrue(obj.signalsBlocked()) + blocker.unblock() + self.assertTrue(not obj.signalsBlocked()) + blocker.reblock() + self.assertTrue(obj.signalsBlocked()) + del blocker + self.assertTrue(not obj.signalsBlocked()) + class TestSignalsBlocked(unittest.TestCase): '''Test case to check if the signals are really blocked''' diff --git a/sources/pyside2/tests/QtCore/qabstractitemmodel_test.py b/sources/pyside2/tests/QtCore/qabstractitemmodel_test.py index 34c15665e..70b610c34 100644 --- a/sources/pyside2/tests/QtCore/qabstractitemmodel_test.py +++ b/sources/pyside2/tests/QtCore/qabstractitemmodel_test.py @@ -54,6 +54,15 @@ class TestQModelIndexInternalPointer(unittest.TestCase): idx = QPersistentModelIndex() m.span(idx) + def testQIdentityProxyModel(self): + sourceModel = QStringListModel(['item1', 'item2']) + sourceIndex = sourceModel.index(0, 0) + sourceData = str(sourceModel.data(sourceIndex, Qt.DisplayRole)) + proxyModel = QIdentityProxyModel() + proxyModel.setSourceModel(sourceModel) + proxyIndex = proxyModel.mapFromSource(sourceIndex) + proxyData = str(proxyModel.data(proxyIndex, Qt.DisplayRole)) + self.assertEqual(sourceData, proxyData) if __name__ == '__main__': unittest.main() diff --git a/sources/pyside2/tests/QtCore/qcoreapplication_test.py b/sources/pyside2/tests/QtCore/qcoreapplication_test.py new file mode 100644 index 000000000..15a905846 --- /dev/null +++ b/sources/pyside2/tests/QtCore/qcoreapplication_test.py @@ -0,0 +1,40 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the test suite of Qt for Python. +## +## $QT_BEGIN_LICENSE:GPL-EXCEPT$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 3 as published by the Free Software +## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +import unittest + +from PySide2.QtCore import QCoreApplication + +class TestQCoreApplication(unittest.TestCase): + def testNoArguments(self): + app = QCoreApplication() + self.assertIsInstance(app, QCoreApplication) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside2/tests/QtCore/qlockfile_test.py b/sources/pyside2/tests/QtCore/qlockfile_test.py new file mode 100644 index 000000000..e943af2b7 --- /dev/null +++ b/sources/pyside2/tests/QtCore/qlockfile_test.py @@ -0,0 +1,55 @@ +#!/usr/bin/python + +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the test suite of Qt for Python. +## +## $QT_BEGIN_LICENSE:GPL-EXCEPT$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 3 as published by the Free Software +## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +'''Test cases for QLockFile''' + +import os, unittest + +from PySide2.QtCore import QDir, QLockFile, QCoreApplication + +class TestQMessageAuthenticationCode (unittest.TestCase): + + def setUp(self): + pid = QCoreApplication.applicationPid() + self._fileName = "{}/pqlockfiletest{}.tmp".format(QDir.tempPath(), pid) + + def tearDown(self): + if (os.path.exists(self._fileName)): + os.remove(self._fileName) + + def test(self): + # Merely exercise the API, no locking against another processes. + lockFile = QLockFile(self._fileName) + self.assertTrue(lockFile.lock()) + self.assertTrue(lockFile.isLocked()) + lockFile.unlock() + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside2/tests/QtCore/qmessageauthenticationcode_test.py b/sources/pyside2/tests/QtCore/qmessageauthenticationcode_test.py new file mode 100644 index 000000000..392e6f052 --- /dev/null +++ b/sources/pyside2/tests/QtCore/qmessageauthenticationcode_test.py @@ -0,0 +1,45 @@ +#!/usr/bin/python + +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the test suite of Qt for Python. +## +## $QT_BEGIN_LICENSE:GPL-EXCEPT$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 3 as published by the Free Software +## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +'''Test cases for QMessageAuthenticationCode''' + +import unittest + +from PySide2.QtCore import QCryptographicHash, QMessageAuthenticationCode + +class TestQMessageAuthenticationCode (unittest.TestCase): + def test(self): + code = QMessageAuthenticationCode(QCryptographicHash.Sha1, 'bla') + result = code.result() + self.assertTrue(result.size() > 0) + print(result.toHex()) + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside2/tests/QtCore/qoperatingsystemversion_test.py b/sources/pyside2/tests/QtCore/qoperatingsystemversion_test.py new file mode 100644 index 000000000..82c571d18 --- /dev/null +++ b/sources/pyside2/tests/QtCore/qoperatingsystemversion_test.py @@ -0,0 +1,40 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the test suite of Qt for Python. +## +## $QT_BEGIN_LICENSE:GPL-EXCEPT$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 3 as published by the Free Software +## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +import unittest +from PySide2.QtCore import QOperatingSystemVersion + +class TestQOperatingSystemVersion(unittest.TestCase): + def test(self): + ov = QOperatingSystemVersion.current() + name = "{} v{}.{}.{}".format(ov.name(), ov.majorVersion(), + ov.minorVersion(), ov.microVersion()) + print(name) + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside2/tests/QtCore/qsocketnotifier_test.py b/sources/pyside2/tests/QtCore/qsocketnotifier_test.py new file mode 100644 index 000000000..0a9b78af3 --- /dev/null +++ b/sources/pyside2/tests/QtCore/qsocketnotifier_test.py @@ -0,0 +1,59 @@ +#!/usr/bin/python + +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the test suite of Qt for Python. +## +## $QT_BEGIN_LICENSE:GPL-EXCEPT$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 3 as published by the Free Software +## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +'''Unit tests for QUuid''' + +import unittest + +from PySide2.QtWidgets import QApplication +from PySide2.QtCore import QSocketNotifier +import socket +import sys +import os + +class QSocketNotifierTest(unittest.TestCase): + def testClass(self): + app = QApplication([]) + # socketpair is not available on Windows + if os.name != "nt": + w_sock, r_sock = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM) + + self.assertIsInstance(r_sock.fileno(), int) + + notifier = QSocketNotifier(r_sock.fileno(), QSocketNotifier.Read) + + self.assertIsNotNone(notifier) + + w_sock.close() + r_sock.close() + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside2/tests/QtGui/CMakeLists.txt b/sources/pyside2/tests/QtGui/CMakeLists.txt index b487a2401..31747659e 100644 --- a/sources/pyside2/tests/QtGui/CMakeLists.txt +++ b/sources/pyside2/tests/QtGui/CMakeLists.txt @@ -23,6 +23,7 @@ PYSIDE_TEST(qcursor_test.py) PYSIDE_TEST(qdatastream_gui_operators_test.py) PYSIDE_TEST(qdesktopservices_test.py) PYSIDE_TEST(qfontmetrics_test.py) +PYSIDE_TEST(qguiapplication_test.py) PYSIDE_TEST(qicon_test.py) PYSIDE_TEST(qitemselection_test.py) PYSIDE_TEST(qmatrix_test.py) diff --git a/sources/pyside2/tests/QtGui/qguiapplication_test.py b/sources/pyside2/tests/QtGui/qguiapplication_test.py new file mode 100644 index 000000000..d1a044655 --- /dev/null +++ b/sources/pyside2/tests/QtGui/qguiapplication_test.py @@ -0,0 +1,40 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the test suite of Qt for Python. +## +## $QT_BEGIN_LICENSE:GPL-EXCEPT$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 3 as published by the Free Software +## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +import unittest + +from PySide2.QtGui import QGuiApplication + +class TestQGuiApplication(unittest.TestCase): + def testNoArguments(self): + app = QGuiApplication() + self.assertIsInstance(app, QGuiApplication) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside2/tests/QtWidgets/CMakeLists.txt b/sources/pyside2/tests/QtWidgets/CMakeLists.txt index b350133f9..4bc17ebee 100644 --- a/sources/pyside2/tests/QtWidgets/CMakeLists.txt +++ b/sources/pyside2/tests/QtWidgets/CMakeLists.txt @@ -84,6 +84,7 @@ PYSIDE_TEST(qabstracttextdocumentlayout_test.py) PYSIDE_TEST(qaction_test.py) PYSIDE_TEST(qapp_issue_585.py) PYSIDE_TEST(qapp_test.py) +PYSIDE_TEST(qapplication_test.py) PYSIDE_TEST(qapplication_exit_segfault_test.py) PYSIDE_TEST(qapplication_singleton_test.py) PYSIDE_TEST(qbrush_test.py) diff --git a/sources/pyside2/tests/QtWidgets/qapplication_test.py b/sources/pyside2/tests/QtWidgets/qapplication_test.py new file mode 100644 index 000000000..b29aba6ac --- /dev/null +++ b/sources/pyside2/tests/QtWidgets/qapplication_test.py @@ -0,0 +1,40 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the test suite of Qt for Python. +## +## $QT_BEGIN_LICENSE:GPL-EXCEPT$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 3 as published by the Free Software +## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +import unittest + +from PySide2.QtWidgets import QApplication + +class TestQApplication(unittest.TestCase): + def testNoArguments(self): + app = QApplication() + self.assertIsInstance(app, QApplication) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside2/tests/QtWidgets/qstyle_test.py b/sources/pyside2/tests/QtWidgets/qstyle_test.py index 38b457a82..eb2a73d29 100644 --- a/sources/pyside2/tests/QtWidgets/qstyle_test.py +++ b/sources/pyside2/tests/QtWidgets/qstyle_test.py @@ -29,7 +29,20 @@ import unittest from helper import UsesQApplication -from PySide2.QtWidgets import QWidget, QLabel, QFontComboBox, QStyleFactory +from PySide2.QtGui import QWindow +from PySide2.QtWidgets import (QApplication, QFontComboBox, QLabel, QProxyStyle, + QStyleFactory, QWidget) + +class ProxyStyle(QProxyStyle): + + def __init__(self, style): + QProxyStyle.__init__(self, style) + self.polished = 0 + + def polish(self, widget): + self.polished = self.polished + 1 + super(ProxyStyle, self).polish(widget) + class SetStyleTest(UsesQApplication): '''Tests setting the same QStyle for all objects in a UI hierarchy.''' @@ -54,6 +67,17 @@ class SetStyleTest(UsesQApplication): style = QStyleFactory.create(QStyleFactory.keys()[0]) setStyleHelper(container, style) + def testSetProxyStyle(self): + label = QLabel("QtWidgets/ProxyStyle test") + baseStyle = QStyleFactory.create(QApplication.instance().style().objectName()) + self.assertTrue(baseStyle) + proxyStyle = ProxyStyle(baseStyle) + label.setStyle(proxyStyle) + label.show() + while not label.windowHandle().isExposed(): + QApplication.instance().processEvents() + self.assertTrue(proxyStyle.polished > 0) + if __name__ == '__main__': unittest.main() diff --git a/sources/pyside2/tests/registry/exists_darwin_5_9_4_ci.py b/sources/pyside2/tests/registry/exists_darwin_5_9_4_ci.py index 95f3fe237..63a74ff07 100644 --- a/sources/pyside2/tests/registry/exists_darwin_5_9_4_ci.py +++ b/sources/pyside2/tests/registry/exists_darwin_5_9_4_ci.py @@ -14556,7 +14556,7 @@ if "PySide2.QtMultimedia" in sys.modules: "QMediaResource.videoCodec": (), # class PySide2.QtMultimedia.QMediaTimeRange: - "QMediaTimeRange.__init__": [(), ('PySide2.QtMultimedia.QMediaTimeRange',), ('int', 'int')], + "QMediaTimeRange.__init__": [(), ('PySide2.QtMultimedia.QMediaTimeInterval',), ('PySide2.QtMultimedia.QMediaTimeRange',), ('int', 'int')], "QMediaTimeRange.__copy__": (), "QMediaTimeRange.addInterval": ('int', 'int'), "QMediaTimeRange.addTimeRange": ('PySide2.QtMultimedia.QMediaTimeRange',), diff --git a/sources/pyside2/tests/registry/exists_linux_5_9_4_ci.py b/sources/pyside2/tests/registry/exists_linux_5_9_4_ci.py index 79e826258..c552e21f0 100644 --- a/sources/pyside2/tests/registry/exists_linux_5_9_4_ci.py +++ b/sources/pyside2/tests/registry/exists_linux_5_9_4_ci.py @@ -14349,7 +14349,7 @@ if "PySide2.QtMultimedia" in sys.modules: "QMediaResource.videoCodec": (), # class PySide2.QtMultimedia.QMediaTimeRange: - "QMediaTimeRange.__init__": [(), ('PySide2.QtMultimedia.QMediaTimeRange',), ('int', 'int')], + "QMediaTimeRange.__init__": [(), ('PySide2.QtMultimedia.QMediaTimeInterval',), ('PySide2.QtMultimedia.QMediaTimeRange',), ('int', 'int')], "QMediaTimeRange.__copy__": (), "QMediaTimeRange.addInterval": ('int', 'int'), "QMediaTimeRange.addTimeRange": ('PySide2.QtMultimedia.QMediaTimeRange',), diff --git a/sources/pyside2/tests/registry/exists_win32_5_9_4_ci.py b/sources/pyside2/tests/registry/exists_win32_5_9_4_ci.py index 20c30e1a3..01e572e21 100644 --- a/sources/pyside2/tests/registry/exists_win32_5_9_4_ci.py +++ b/sources/pyside2/tests/registry/exists_win32_5_9_4_ci.py @@ -14657,7 +14657,7 @@ if "PySide2.QtMultimedia" in sys.modules: "QMediaResource.videoCodec": (), # class PySide2.QtMultimedia.QMediaTimeRange: - "QMediaTimeRange.__init__": [(), ('PySide2.QtMultimedia.QMediaTimeRange',), ('int', 'int')], + "QMediaTimeRange.__init__": [(), ('PySide2.QtMultimedia.QMediaTimeInterval',), ('PySide2.QtMultimedia.QMediaTimeRange',), ('int', 'int')], "QMediaTimeRange.__copy__": (), "QMediaTimeRange.addInterval": ('int', 'int'), "QMediaTimeRange.addTimeRange": ('PySide2.QtMultimedia.QMediaTimeRange',), diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 8e1732be9..23feeafad 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -1878,6 +1878,12 @@ static inline QString msgUnmatchedParameterType(const ArgumentModelItem &arg, in return result; } +static inline QString msgUnmatchedReturnType(const FunctionModelItem &functionItem) +{ + return QLatin1String("unmatched return type '") + + functionItem->type().toString() + QLatin1Char('\''); +} + static inline QString msgVoidParameterType(const ArgumentModelItem &arg, int n) { QString result; @@ -1888,6 +1894,22 @@ static inline QString msgVoidParameterType(const ArgumentModelItem &arg, int n) return result; } +static QString msgSkippingFunction(const FunctionModelItem &functionItem, + const QString &signature, const QString &why) +{ + QString result; + QTextStream str(&result); + str << "skipping "; + if (functionItem->isAbstract()) + str << "abstract "; + str << "function '" << signature << "', " << why; + if (functionItem->isAbstract()) { + str << "\nThis will lead to compilation errors due to not " + "being able to instantiate the wrapper."; + } + return result; +} + static inline AbstractMetaFunction::FunctionType functionTypeFromCodeModel(CodeModel::FunctionType ft) { AbstractMetaFunction::FunctionType result = AbstractMetaFunction::NormalFunction; @@ -2048,13 +2070,11 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel bool ok; AbstractMetaType *type = translateType(returnType, &ok); - if (!ok) { Q_ASSERT(type == 0); - qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("skipping function '%1', unmatched return type '%2'") - .arg(originalQualifiedSignatureWithReturn, - functionItem->type().toString()); + const QString reason = msgUnmatchedReturnType(functionItem); + qCWarning(lcShiboken, "%s", + qPrintable(msgSkippingFunction(functionItem, originalQualifiedSignatureWithReturn, reason))); m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn, AbstractMetaBuilder::UnmatchedReturnType); delete metaFunction; return nullptr; @@ -2104,9 +2124,8 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel } Q_ASSERT(metaType == 0); const QString reason = msgUnmatchedParameterType(arg, i); - qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("skipping function '%1', %2") - .arg(originalQualifiedSignatureWithReturn, reason); + qCWarning(lcShiboken, "%s", + qPrintable(msgSkippingFunction(functionItem, originalQualifiedSignatureWithReturn, reason))); const QString rejectedFunctionSignature = originalQualifiedSignatureWithReturn + QLatin1String(": ") + reason; m_rejectedFunctions.insert(rejectedFunctionSignature, AbstractMetaBuilder::UnmatchedArgumentType); @@ -2116,9 +2135,8 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel if (metaType == Q_NULLPTR) { const QString reason = msgVoidParameterType(arg, i); - qCWarning(lcShiboken).noquote().nospace() - << QString::fromLatin1("skipping function '%1': %2") - .arg(originalQualifiedSignatureWithReturn, reason); + qCWarning(lcShiboken, "%s", + qPrintable(msgSkippingFunction(functionItem, originalQualifiedSignatureWithReturn, reason))); const QString rejectedFunctionSignature = originalQualifiedSignatureWithReturn + QLatin1String(": ") + reason; m_rejectedFunctions.insert(rejectedFunctionSignature, AbstractMetaBuilder::UnmatchedArgumentType); diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp index ba33f78d9..5be7050bf 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp @@ -189,6 +189,11 @@ AbstractMetaTypeCList AbstractMetaType::nestedArrayTypes() const return result; } +bool AbstractMetaType::isConstRef() const +{ + return isConstant() && m_referenceType == LValueReference && indirections() == 0; +} + QString AbstractMetaType::cppSignature() const { if (m_cachedCppSignature.isEmpty()) @@ -201,10 +206,8 @@ AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() con if (m_typeEntry->isTemplateArgument() || m_referenceType == RValueReference) return InvalidPattern; - if (m_typeEntry->isPrimitive() && (!actualIndirections() - || (isConstant() && m_referenceType == LValueReference && !indirections()))) { + if (m_typeEntry->isPrimitive() && (actualIndirections() == 0 || isConstRef())) return PrimitivePattern; - } if (m_typeEntry->isVoid()) return NativePointerPattern; @@ -212,7 +215,7 @@ AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() con if (m_typeEntry->isVarargs()) return VarargsPattern; - if (m_typeEntry->isEnum() && actualIndirections() == 0) + if (m_typeEntry->isEnum() && (actualIndirections() == 0 || isConstRef())) return EnumPattern; if (m_typeEntry->isObject()) { @@ -228,8 +231,7 @@ AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() con if (m_typeEntry->isSmartPointer() && indirections() == 0) return SmartPointerPattern; - if (m_typeEntry->isFlags() && indirections() == 0 - && (isConstant() == (m_referenceType == LValueReference))) + if (m_typeEntry->isFlags() && (actualIndirections() == 0 || isConstRef())) return FlagsPattern; if (m_typeEntry->isArray()) @@ -1754,7 +1756,7 @@ void AbstractMetaClass::addDefaultConstructor() f->setArguments(AbstractMetaArgumentList()); f->setDeclaringClass(this); - f->setAttributes(AbstractMetaAttributes::Public | AbstractMetaAttributes::FinalInTargetLang); + f->setAttributes(Public | FinalInTargetLang | AddedMethod); f->setImplementingClass(this); f->setOriginalAttributes(f->attributes()); @@ -1782,7 +1784,7 @@ void AbstractMetaClass::addDefaultCopyConstructor(bool isPrivate) arg->setName(name()); f->addArgument(arg); - AbstractMetaAttributes::Attributes attr = AbstractMetaAttributes::FinalInTargetLang; + AbstractMetaAttributes::Attributes attr = FinalInTargetLang | AddedMethod; if (isPrivate) attr |= AbstractMetaAttributes::Private; else @@ -2154,8 +2156,11 @@ void AbstractMetaClass::fixFunctions() funcsToAdd << sf; } - for (AbstractMetaFunction *f : qAsConst(funcsToAdd)) - funcs << f->copy(); + for (AbstractMetaFunction *f : qAsConst(funcsToAdd)) { + AbstractMetaFunction *copy = f->copy(); + (*copy) += AddedMethod; + funcs.append(copy); + } if (superClass) superClass = superClass->baseClass(); diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h index c31c5a386..d1a0fbf88 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.h +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h @@ -137,7 +137,9 @@ public: FinalCppClass = 0x00100000, VirtualCppMethod = 0x00200000, OverriddenCppMethod = 0x00400000, - FinalCppMethod = 0x00800000 + FinalCppMethod = 0x00800000, + // Add by meta builder (implicit constructors, inherited methods, etc) + AddedMethod = 0x01000000 }; Q_DECLARE_FLAGS(Attributes, Attribute) Q_FLAG(Attribute) @@ -434,6 +436,8 @@ public: m_constant = constant; } + bool isConstRef() const; + ReferenceType referenceType() const { return m_referenceType; } void setReferenceType(ReferenceType ref) { m_referenceType = ref; } diff --git a/sources/shiboken2/ApiExtractor/docparser.cpp b/sources/shiboken2/ApiExtractor/docparser.cpp index 0cbae33eb..9305332ba 100644 --- a/sources/shiboken2/ApiExtractor/docparser.cpp +++ b/sources/shiboken2/ApiExtractor/docparser.cpp @@ -82,6 +82,7 @@ bool DocParser::skipForQuery(const AbstractMetaFunction *func) { // Skip private functions and copies created by AbstractMetaClass::fixFunctions() if (!func || func->isPrivate() + || (func->attributes() & AbstractMetaAttributes::AddedMethod) != 0 || func->isModifiedRemoved() || func->declaringClass() != func->ownerClass() || func->isCastOperator()) { @@ -124,9 +125,9 @@ QString DocParser::msgCannotFindDocumentation(const QString &fileName, const AbstractMetaFunction *function, const QString &query) { - return msgCannotFindDocumentation(fileName, "function", - metaClass->name() + QLatin1String("::") + function->name() + QLatin1String("()"), - query); + const QString name = metaClass->name() + QLatin1String("::") + + function->minimalSignature(); + return msgCannotFindDocumentation(fileName, "function", name, query); } QString DocParser::msgCannotFindDocumentation(const QString &fileName, diff --git a/sources/shiboken2/ApiExtractor/qtdocparser.cpp b/sources/shiboken2/ApiExtractor/qtdocparser.cpp index 8917f801e..b0058d6ea 100644 --- a/sources/shiboken2/ApiExtractor/qtdocparser.cpp +++ b/sources/shiboken2/ApiExtractor/qtdocparser.cpp @@ -35,6 +35,8 @@ #include <QtCore/QDir> #include <QtCore/QFile> #include <QtCore/QTextStream> +#include <QtCore/QXmlStreamAttributes> +#include <QtCore/QXmlStreamReader> #include <QUrl> Documentation QtDocParser::retrieveModuleDocumentation() @@ -48,9 +50,6 @@ static void formatFunctionArgTypeQuery(QTextStream &str, const AbstractMetaArgum if (metaType->isConstant()) str << "const " ; switch (metaType->typeUsagePattern()) { - case AbstractMetaType::PrimitivePattern: - str << metaType->name(); - break; case AbstractMetaType::FlagsPattern: { // Modify qualified name "QFlags<Qt::AlignmentFlag>" with name "Alignment" // to "Qt::Alignment" as seen by qdoc. @@ -92,6 +91,119 @@ static void formatFunctionArgTypeQuery(QTextStream &str, const AbstractMetaArgum str << ' ' << QByteArray(metaType->indirections(), '*'); } +enum FunctionMatchFlags +{ + MatchArgumentCount = 0x1, + MatchArgumentType = 0x2, + DescriptionOnly = 0x4 +}; + +static QString functionXQuery(const QString &classQuery, + const AbstractMetaFunction *func, + unsigned matchFlags = MatchArgumentCount | MatchArgumentType + | DescriptionOnly) +{ + QString result; + QTextStream str(&result); + const AbstractMetaArgumentList &arguments = func->arguments(); + str << classQuery << "/function[@name=\"" << func->originalName() + << "\" and @const=\"" << (func->isConstant() ? "true" : "false") << '"'; + if (matchFlags & MatchArgumentCount) + str << " and count(parameter)=" << arguments.size(); + str << ']'; + if (!arguments.isEmpty() && (matchFlags & MatchArgumentType)) { + for (int i = 0, size = arguments.size(); i < size; ++i) { + str << "/parameter[" << (i + 1) << "][@type=\""; + // Fixme: Use arguments.at(i)->type()->originalTypeDescription() + // instead to get unresolved typedefs? + formatFunctionArgTypeQuery(str, arguments.at(i)); + str << "\"]/.."; + } + } + if (matchFlags & DescriptionOnly) + str << "/description"; + return result; +} + +static QStringList signaturesFromWebXml(QString w) +{ + QStringList result; + if (w.isEmpty()) + return result; + w.prepend(QLatin1String("<root>")); // Fake root element + w.append(QLatin1String("</root>")); + QXmlStreamReader reader(w); + while (!reader.atEnd()) { + if (reader.readNext() == QXmlStreamReader::StartElement + && reader.name() == QLatin1String("function")) { + result.append(reader.attributes().value(QStringLiteral("signature")).toString()); + } + } + return result; +} + +static QString msgArgumentCountMatch(const AbstractMetaFunction *func, + const QStringList &matches) +{ + QString result; + QTextStream str(&result); + str << "\n Note: Querying for the argument count==" + << func->arguments().size() << " only yields " << matches.size() + << " matches"; + if (!matches.isEmpty()) + str << ": \"" << matches.join(QLatin1String("\", \"")) << '"'; + return result; +} + +QString QtDocParser::queryFunctionDocumentation(const QString &sourceFileName, + const AbstractMetaClass* metaClass, + const QString &classQuery, + const AbstractMetaFunction *func, + const DocModificationList &signedModifs, + QXmlQuery &xquery, + QString *errorMessage) +{ + DocModificationList funcModifs; + for (const DocModification &funcModif : signedModifs) { + if (funcModif.signature() == func->minimalSignature()) + funcModifs.append(funcModif); + } + + // Properties + if (func->isPropertyReader() || func->isPropertyWriter() || func->isPropertyResetter()) { + const QString propertyQuery = classQuery + QLatin1String("/property[@name=\"") + + func->propertySpec()->name() + QLatin1String("\"]/description"); + const QString properyDocumentation = getDocumentation(xquery, propertyQuery, funcModifs); + if (properyDocumentation.isEmpty()) + *errorMessage = msgCannotFindDocumentation(sourceFileName, metaClass, func, propertyQuery); + return properyDocumentation; + } + + // Query with full match of argument types + const QString fullQuery = functionXQuery(classQuery, func); + const QString result = getDocumentation(xquery, fullQuery, funcModifs); + if (!result.isEmpty()) + return result; + *errorMessage = msgCannotFindDocumentation(sourceFileName, metaClass, func, fullQuery); + if (func->arguments().isEmpty()) // No arguments, can't be helped + return result; + // Test whether some mismatch in argument types occurred by checking for + // the argument count only. Include the outer <function> element. + QString countOnlyQuery = functionXQuery(classQuery, func, MatchArgumentCount); + QStringList signatures = + signaturesFromWebXml(getDocumentation(xquery, countOnlyQuery, funcModifs)); + if (signatures.size() == 1) { + // One match was found. Repeat the query restricted to the <description> + // element and use the result with a warning. + countOnlyQuery = functionXQuery(classQuery, func, MatchArgumentCount | DescriptionOnly); + errorMessage->append(QLatin1String("\n Falling back to \"") + signatures.constFirst() + + QLatin1String("\" obtained by matching the argument count only.")); + return getDocumentation(xquery, countOnlyQuery, funcModifs); + } + *errorMessage += msgArgumentCountMatch(func, signatures); + return result; +} + void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass) { if (!metaClass) @@ -144,40 +256,16 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass) qCWarning(lcShiboken(), "%s", qPrintable(msgCannotFindDocumentation(sourceFileName, "class", className, query))); metaClass->setDocumentation(doc); - //Functions Documentation + QString errorMessage; const AbstractMetaFunctionList &funcs = DocParser::documentableFunctions(metaClass); for (AbstractMetaFunction *func : funcs) { - query.clear(); - QTextStream str(&query); - str << classQuery; - // properties - if (func->isPropertyReader() || func->isPropertyWriter() || func->isPropertyResetter()) { - str << "/property[@name=\"" << func->propertySpec()->name() << "\"]"; - } else { // normal methods - str << "/function[@name=\"" << func->originalName() << "\" and count(parameter)=" - << func->arguments().count() << " and @const=\"" - << (func->isConstant() ? "true" : "false") << "\"]"; - - const AbstractMetaArgumentList &arguments = func->arguments(); - for (int i = 0, size = arguments.size(); i < size; ++i) { - str << "/parameter[" << (i + 1) << "][@type=\""; - formatFunctionArgTypeQuery(str, arguments.at(i)); - str << "\"]/.."; - } - } - str << "/description"; - DocModificationList funcModifs; - for (const DocModification &funcModif : qAsConst(signedModifs)) { - if (funcModif.signature() == func->minimalSignature()) - funcModifs.append(funcModif); - } - doc.setValue(getDocumentation(xquery, query, funcModifs)); - if (doc.isEmpty()) { - qCWarning(lcShiboken(), "%s", - qPrintable(msgCannotFindDocumentation(sourceFileName, metaClass, func, query))); - } - func->setDocumentation(doc); + const QString documentation = + queryFunctionDocumentation(sourceFileName, metaClass, classQuery, + func, signedModifs, xquery, &errorMessage); + if (!errorMessage.isEmpty()) + qCWarning(lcShiboken(), "%s", qPrintable(errorMessage)); + func->setDocumentation(Documentation(documentation)); } #if 0 // Fields @@ -206,18 +294,28 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass) } } +static QString qmlReferenceLink(const QFileInfo &qmlModuleFi) +{ + QString result; + QTextStream(&result) << "<para>The module also provides <link" + << " type=\"page\"" + << " page=\"http://doc.qt.io/qt-5/" << qmlModuleFi.baseName() << ".html\"" + << ">QML types</link>.</para>"; + return result; +} + Documentation QtDocParser::retrieveModuleDocumentation(const QString& name) { // TODO: This method of acquiring the module name supposes that the target language uses // dots as module separators in package names. Improve this. QString moduleName = name; moduleName.remove(0, name.lastIndexOf(QLatin1Char('.')) + 1); - QString sourceFile = documentationDataDirectory() + QLatin1Char('/') - + moduleName.toLower() + QLatin1String(".xml"); + const QString prefix = documentationDataDirectory() + QLatin1Char('/') + + moduleName.toLower(); + QString sourceFile = prefix + QLatin1String(".xml"); if (!QFile::exists(sourceFile)) - sourceFile = documentationDataDirectory() + QLatin1Char('/') - + moduleName.toLower() + QLatin1String("-module.webxml"); + sourceFile = prefix + QLatin1String("-module.webxml"); if (!QFile::exists(sourceFile)) { qCWarning(lcShiboken).noquote().nospace() << "Can't find qdoc file for module " << name << ", tried: " @@ -231,8 +329,22 @@ Documentation QtDocParser::retrieveModuleDocumentation(const QString& name) // Module documentation QString query = QLatin1String("/WebXML/document/module[@name=\"") + moduleName + QLatin1String("\"]/description"); - const Documentation doc = getDocumentation(xquery, query, DocModificationList()); - if (doc.isEmpty()) + Documentation doc = getDocumentation(xquery, query, DocModificationList()); + if (doc.isEmpty()) { qCWarning(lcShiboken(), "%s", qPrintable(msgCannotFindDocumentation(sourceFile, "module", name, query))); + return doc; + } + + // If a QML module info file exists, insert a link to the Qt docs. + const QFileInfo qmlModuleFi(prefix + QLatin1String("-qmlmodule.webxml")); + if (qmlModuleFi.isFile()) { + QString docString = doc.value(); + const int pos = docString.lastIndexOf(QLatin1String("</description>")); + if (pos != -1) { + docString.insert(pos, qmlReferenceLink(qmlModuleFi)); + doc.setValue(docString); + } + } + return doc; } diff --git a/sources/shiboken2/ApiExtractor/qtdocparser.h b/sources/shiboken2/ApiExtractor/qtdocparser.h index 3ea0122b4..b5f0e51d8 100644 --- a/sources/shiboken2/ApiExtractor/qtdocparser.h +++ b/sources/shiboken2/ApiExtractor/qtdocparser.h @@ -38,6 +38,15 @@ public: void fillDocumentation(AbstractMetaClass* metaClass) override; Documentation retrieveModuleDocumentation() override; Documentation retrieveModuleDocumentation(const QString& name) override; + +private: + QString queryFunctionDocumentation(const QString &sourceFileName, + const AbstractMetaClass* metaClass, + const QString &classQuery, + const AbstractMetaFunction *func, + const DocModificationList &signedModifs, + QXmlQuery &xquery, + QString *errorMessage); }; #endif // QTDOCPARSER_H diff --git a/sources/shiboken2/CMakeLists.txt b/sources/shiboken2/CMakeLists.txt index 3efc6fefe..0a2920e4f 100644 --- a/sources/shiboken2/CMakeLists.txt +++ b/sources/shiboken2/CMakeLists.txt @@ -19,8 +19,8 @@ if (USE_PYTHON_VERSION) find_package(PythonInterp ${USE_PYTHON_VERSION} REQUIRED) find_package(PythonLibs ${USE_PYTHON_VERSION} REQUIRED) else() - find_package(PythonInterp 2.6) - find_package(PythonLibs 2.6) + find_package(PythonInterp 2.7) + find_package(PythonLibs 2.7) endif() macro(get_python_arch) diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp index 7206d7ca8..489d498f9 100644 --- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp +++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp @@ -464,8 +464,10 @@ QString QtXmlToSphinx::transform(const QString& doc) while (!reader.atEnd()) { QXmlStreamReader::TokenType token = reader.readNext(); if (reader.hasError()) { - const QString message = QLatin1String("XML Error: ") + reader.errorString() - + QLatin1Char('\n') + doc; + QString message; + QTextStream(&message) << "XML Error " + << reader.errorString() << " at " << reader.lineNumber() + << ':' << reader.columnNumber() << '\n' << doc; m_output << INDENT << message; qCWarning(lcShiboken).noquote().nospace() << message; break; @@ -2194,44 +2196,61 @@ void QtDocGenerator::writeAdditionalDocumentation() qPrintable(FileOut::msgCannotOpenForReading(additionalDocumentationFile))); return; } - const QByteArray contents = additionalDocumentationFile.readAll(); - const QStringList lines = QFile::decodeName(contents).split(QLatin1Char('\n')); - QFileInfoList additionalDocFiles; - additionalDocFiles.reserve(lines.size()); - for (const QString &lineIn : lines) { - const QString line = lineIn.trimmed(); - if (!line.isEmpty() && !line.startsWith(QLatin1Char('#'))) { + + QDir outDir(outputDirectory()); + const QString rstSuffix = fileNameSuffix(); + + QString errorMessage; + int successCount = 0; + int count = 0; + + QString targetDir = outDir.absolutePath(); + + while (!additionalDocumentationFile.atEnd()) { + const QByteArray lineBA = additionalDocumentationFile.readLine().trimmed(); + if (lineBA.isEmpty() || lineBA.startsWith('#')) + continue; + const QString line = QFile::decodeName(lineBA); + // Parse "[directory]" specification + if (line.size() > 2 && line.startsWith(QLatin1Char('[')) && line.endsWith(QLatin1Char(']'))) { + const QString dir = line.mid(1, line.size() - 2); + if (dir.isEmpty() || dir == QLatin1String(".")) { + targetDir = outDir.absolutePath(); + } else { + if (!outDir.exists(dir) && !outDir.mkdir(dir)) { + qCWarning(lcShiboken, "Cannot create directory %s under %s", + qPrintable(dir), + qPrintable(QDir::toNativeSeparators(outputDirectory()))); + break; + } + targetDir = outDir.absoluteFilePath(dir); + } + } else { + // Normal file entry QFileInfo fi(m_docDataDir + QLatin1Char('/') + line); if (fi.isFile()) { - additionalDocFiles.append(fi); + const QString rstFileName = fi.baseName() + rstSuffix; + const QString rstFile = targetDir + QLatin1Char('/') + rstFileName; + if (QtXmlToSphinx::convertToRst(this, fi.absoluteFilePath(), + rstFile, QString(), &errorMessage)) { + ++successCount; + qCDebug(lcShiboken).nospace().noquote() << __FUNCTION__ + << " converted " << fi.fileName() + << ' ' << rstFileName; + } else { + qCWarning(lcShiboken, "%s", qPrintable(errorMessage)); + } } else { qCWarning(lcShiboken, "%s", qPrintable(msgNonExistentAdditionalDocFile(m_docDataDir, line))); } + ++count; } } additionalDocumentationFile.close(); - const QString rstPrefix = outputDirectory() + QLatin1Char('/'); - const QString rstSuffix = fileNameSuffix(); - - QString errorMessage; - int successCount = 0; - for (const QFileInfo &additionalDocFile : additionalDocFiles) { - const QString rstFileName = additionalDocFile.baseName() + rstSuffix; - const QString rstFile = rstPrefix + rstFileName; - if (QtXmlToSphinx::convertToRst(this, additionalDocFile.absoluteFilePath(), - rstFile, QString(), &errorMessage)) { - ++successCount; - qCDebug(lcShiboken).nospace().noquote() << __FUNCTION__ - << " converted " << additionalDocFile.fileName() - << ' ' << rstFileName; - } else { - qCWarning(lcShiboken, "%s", qPrintable(errorMessage)); - } - } qCInfo(lcShiboken, "Created %d/%d additional documentation files.", - successCount, additionalDocFiles.size()); + successCount, count); } bool QtDocGenerator::doSetup(const QMap<QString, QString>& args) diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp index b2734418c..6165ef009 100644 --- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp @@ -1996,6 +1996,17 @@ static QString getConverterTypeSystemVariableArgument(const QString& code, int p return arg; } typedef QPair<QString, QString> StringPair; + +static QString msgCannotFindType(const QString &type, const QString &variable, + const QString &why) +{ + QString result; + QTextStream(&result) << "Could not find type '" + << type << "' for use in '" << variable << "' conversion: " << why + << "\nMake sure to use the full C++ name, e.g. 'Namespace::Class'."; + return result; +} + void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVariable converterVariable, QString& code) { QVector<StringPair> replacements; @@ -2005,12 +2016,12 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa const QStringList list = match.capturedTexts(); QString conversionString = list.constFirst(); QString conversionTypeName = list.constLast(); - const AbstractMetaType* conversionType = buildAbstractMetaTypeFromString(conversionTypeName); + QString message; + const AbstractMetaType *conversionType = buildAbstractMetaTypeFromString(conversionTypeName, &message); if (!conversionType) { - qFatal(qPrintable(QString::fromLatin1("Could not find type '%1' for use in '%2' conversion. " - "Make sure to use the full C++ name, e.g. 'Namespace::Class'.") - .arg(conversionTypeName).arg(m_typeSystemConvName[converterVariable])), NULL); - + qFatal("%s", qPrintable(msgCannotFindType(conversionTypeName, + m_typeSystemConvName[converterVariable], + message))); } QString conversion; QTextStream c(&conversion); @@ -2312,7 +2323,8 @@ bool ShibokenGenerator::isCopyable(const AbstractMetaClass *metaClass) return false; } -AbstractMetaType* ShibokenGenerator::buildAbstractMetaTypeFromString(QString typeSignature) +AbstractMetaType *ShibokenGenerator::buildAbstractMetaTypeFromString(QString typeSignature, + QString *errorMessage) { typeSignature = typeSignature.trimmed(); if (typeSignature.startsWith(QLatin1String("::"))) @@ -2348,9 +2360,10 @@ AbstractMetaType* ShibokenGenerator::buildAbstractMetaTypeFromString(QString typ typeString.remove(0, 2); QString adjustedTypeName = typeString; - QStringList instantiatedTypes; + AbstractMetaTypeList instantiations; int lpos = typeString.indexOf(QLatin1Char('<')); if (lpos > -1) { + QStringList instantiatedTypes; int rpos = typeString.lastIndexOf(QLatin1Char('>')); if ((lpos != -1) && (rpos != -1)) { QString type = typeString.mid(lpos + 1, rpos - lpos - 1); @@ -2369,25 +2382,57 @@ AbstractMetaType* ShibokenGenerator::buildAbstractMetaTypeFromString(QString typ instantiatedTypes << type.mid(start).trimmed(); adjustedTypeName.truncate(lpos); } + for (const QString &instantiatedType : qAsConst(instantiatedTypes)) { + AbstractMetaType *tmplArgType = buildAbstractMetaTypeFromString(instantiatedType); + if (!tmplArgType) { + if (errorMessage) { + QTextStream(errorMessage) << "Cannot find template type \"" + << instantiatedType << "\" for \"" << typeSignature << "\"."; + } + return nullptr; + } + instantiations.append(tmplArgType); + } } - TypeEntry* typeEntry = TypeDatabase::instance()->findType(adjustedTypeName); + TypeEntry *typeEntry = nullptr; + AbstractMetaType::TypeUsagePattern pattern = AbstractMetaType::InvalidPattern; - AbstractMetaType* metaType = 0; - if (typeEntry) { - metaType = new AbstractMetaType(); - metaType->setTypeEntry(typeEntry); - metaType->setIndirections(indirections); - metaType->setReferenceType(refType); - metaType->setConstant(isConst); - metaType->setTypeUsagePattern(AbstractMetaType::ContainerPattern); - for (const QString &instantiation : qAsConst(instantiatedTypes)) { - AbstractMetaType* tmplArgType = buildAbstractMetaTypeFromString(instantiation); - metaType->addInstantiation(tmplArgType); + if (instantiations.size() == 1 + && instantiations.at(0)->typeUsagePattern() == AbstractMetaType::EnumPattern + && adjustedTypeName == QLatin1String("QFlags")) { + pattern = AbstractMetaType::FlagsPattern; + typeEntry = TypeDatabase::instance()->findType(typeSignature); + } else { + typeEntry = TypeDatabase::instance()->findType(adjustedTypeName); + } + + if (!typeEntry) { + if (errorMessage) { + QTextStream(errorMessage) << "Cannot find type \"" << adjustedTypeName + << "\" for \"" << typeSignature << "\"."; } + return nullptr; + } + + AbstractMetaType *metaType = new AbstractMetaType(); + metaType->setTypeEntry(typeEntry); + metaType->setIndirections(indirections); + metaType->setReferenceType(refType); + metaType->setConstant(isConst); + metaType->setTypeUsagePattern(AbstractMetaType::ContainerPattern); + switch (pattern) { + case AbstractMetaType::FlagsPattern: + metaType->setTypeUsagePattern(pattern); + break; + default: + metaType->setInstantiations(instantiations); + metaType->setTypeUsagePattern(AbstractMetaType::ContainerPattern); metaType->decideUsagePattern(); - m_metaTypeFromStringCache.insert(typeSignature, metaType); + break; } + + m_metaTypeFromStringCache.insert(typeSignature, metaType); return metaType; } diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.h b/sources/shiboken2/generator/shiboken2/shibokengenerator.h index d44f4aa66..3271d741d 100644 --- a/sources/shiboken2/generator/shiboken2/shibokengenerator.h +++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.h @@ -467,7 +467,8 @@ public: * \param typeSignature The string describing the type to be built. * \return A new AbstractMetaType object that must be deleted by the caller, or a NULL pointer in case of failure. */ - AbstractMetaType* buildAbstractMetaTypeFromString(QString typeSignature); + AbstractMetaType *buildAbstractMetaTypeFromString(QString typeSignature, + QString *errorMessage = nullptr); /// Creates an AbstractMetaType object from a TypeEntry. AbstractMetaType* buildAbstractMetaTypeFromTypeEntry(const TypeEntry* typeEntry); diff --git a/sources/shiboken2/tests/libsample/objecttype.h b/sources/shiboken2/tests/libsample/objecttype.h index 9d659faa4..bcb4f3332 100644 --- a/sources/shiboken2/tests/libsample/objecttype.h +++ b/sources/shiboken2/tests/libsample/objecttype.h @@ -53,6 +53,10 @@ struct Event Event(EventType eventType) : m_eventType(eventType) {} EventType eventType() { return m_eventType; } + + void setEventType(EventType et) { m_eventType = et; } + void setEventTypeByConstRef(const EventType &et) { m_eventType = et; } + private: EventType m_eventType; }; diff --git a/sources/shiboken2/tests/samplebinding/enum_test.py b/sources/shiboken2/tests/samplebinding/enum_test.py index 0a5a84c4a..7e1cac8c0 100644 --- a/sources/shiboken2/tests/samplebinding/enum_test.py +++ b/sources/shiboken2/tests/samplebinding/enum_test.py @@ -115,6 +115,14 @@ class EnumTest(unittest.TestCase): sum = Event.EventTypeClass.Value1 + Event.EventTypeClass.Value2 self.assertEqual(sum, 1) + def testSetEnum(self): + event = Event(Event.ANY_EVENT) + self.assertEqual(event.eventType(), Event.ANY_EVENT) + event.setEventType(Event.BASIC_EVENT) + self.assertEqual(event.eventType(), Event.BASIC_EVENT) + event.setEventTypeByConstRef(Event.SOME_EVENT) + self.assertEqual(event.eventType(), Event.SOME_EVENT) + def testEnumTpPrintImplementation(self): '''Without SbkEnum.tp_print 'print' returns the enum represented as an int.''' tmpfile = createTempFile() diff --git a/tests/QtQml/qquickitem_grabToImage.py b/tests/QtQml/qquickitem_grabToImage.py deleted file mode 100644 index 91835e689..000000000 --- a/tests/QtQml/qquickitem_grabToImage.py +++ /dev/null @@ -1,79 +0,0 @@ -############################################################################# -## -## Copyright (C) 2017 The Qt Company Ltd. -## Contact: https://www.qt.io/licensing/ -## -## This file is part of the test suite of PySide2. -## -## $QT_BEGIN_LICENSE:GPL-EXCEPT$ -## Commercial License Usage -## Licensees holding valid commercial Qt licenses may use this file in -## accordance with the commercial license agreement provided with the -## Software or, alternatively, in accordance with the terms contained in -## a written agreement between you and The Qt Company. For licensing terms -## and conditions see https://www.qt.io/terms-conditions. For further -## information use the contact form at https://www.qt.io/contact-us. -## -## GNU General Public License Usage -## Alternatively, this file may be used under the terms of the GNU -## General Public License version 3 as published by the Free Software -## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -## included in the packaging of this file. Please review the following -## information to ensure the GNU General Public License requirements will -## be met: https://www.gnu.org/licenses/gpl-3.0.html. -## -## $QT_END_LICENSE$ -## -############################################################################# - -import unittest -from helper import adjust_filename, TimedQApplication -from PySide2 import QtCore, QtGui, QtQuick - -class TestGrabToSharedPointerImage(TimedQApplication): - def setUp(self): - TimedQApplication.setUp(self, 1000) - - def testQQuickItemGrabToImageSharedPointer(self): - view = QtQuick.QQuickView() - view.setSource(QtCore.QUrl.fromLocalFile( - adjust_filename('qquickitem_grabToImage.qml', __file__))) - view.show() - - # Get the QQuickItem objects for the blue Rectangle and the Image item. - root = view.rootObject() - blueRectangle = root.findChild(QtQuick.QQuickItem, "blueRectangle") - imageContainer = root.findChild(QtQuick.QQuickItem, "imageContainer") - - # Start the image grabbing. - grabResultSharedPtr = blueRectangle.grabToImage() - - # Implicit call of operator bool() of the smart pointer, to check that it holds - # a valid pointer. - self.assertTrue(grabResultSharedPtr) - - self.grabbedColor = None - def onGrabReady(): - # Signal early exit. - QtCore.QTimer.singleShot(0, self.app.quit) - - # Show the grabbed image in the QML Image item. - imageContainer.setProperty("source", grabResultSharedPtr.url()) - - # Wait for signal when grabbing is complete. - grabResultSharedPtr.ready.connect(onGrabReady) - self.app.exec_() - - # Get the first pixel color of the grabbed image. - self.image = grabResultSharedPtr.image() - self.assertTrue(self.image) - self.grabbedColor = self.image.pixelColor(0,0) - self.assertTrue(self.grabbedColor.isValid()) - - # Compare the grabbed color with the one we set in the rectangle. - blueColor = QtGui.QColor("blue") - self.assertEqual(self.grabbedColor, blueColor) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/QtQml/qquickitem_grabToImage.qml b/tests/QtQml/qquickitem_grabToImage.qml deleted file mode 100644 index d103cf076..000000000 --- a/tests/QtQml/qquickitem_grabToImage.qml +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of PySide2. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -Item { - id: root - width: 600 - height: 600 - - Rectangle { - id: blue - objectName: "blueRectangle" - width: 200 - height: 200 - anchors.top: root.top - anchors.horizontalCenter: root.horizontalCenter - color: "blue" - } - - Text { - text: qsTr("Original blue rectangle") - anchors.left: blue.right - anchors.verticalCenter: blue.verticalCenter - } - - Image { - id: imageContainer - objectName: "imageContainer" - width: 200 - height: 200 - anchors.bottom: root.bottom - anchors.horizontalCenter: root.horizontalCenter - } - - Text { - text: qsTr("Image with the source URL set to the result of calling QQuickItem::grabToImage on the rectangle. If you see a second blue rectangle, that means it works.") - anchors.left: imageContainer.right - anchors.verticalCenter: imageContainer.verticalCenter - wrapMode: Text.WrapAtWordBoundaryOrAnywhere - width: 200 - } - -} |