diff options
160 files changed, 3511 insertions, 7126 deletions
diff --git a/.qmake.conf b/.qmake.conf index a2a0d4189..aefa1e701 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -1,3 +1,3 @@ load(qt_build_config) -MODULE_VERSION = 5.7.1 +MODULE_VERSION = 5.8.0 diff --git a/examples/uitools/uitools.pro b/examples/uitools/uitools.pro index 39bf8e30b..bc2285d80 100644 --- a/examples/uitools/uitools.pro +++ b/examples/uitools/uitools.pro @@ -1,4 +1,4 @@ TEMPLATE = subdirs SUBDIRS = multipleinheritance -!wince: SUBDIRS += textfinder +SUBDIRS += textfinder diff --git a/src/androiddeployqt/main.cpp b/src/androiddeployqt/main.cpp index 8a8e59172..c1fd13061 100644 --- a/src/androiddeployqt/main.cpp +++ b/src/androiddeployqt/main.cpp @@ -1960,7 +1960,7 @@ bool fetchRemoteModifications(Options *options, const QString &directory) if (!ok) continue; - options->remoteModificationDate = QDateTime::fromTime_t(time); + options->remoteModificationDate = QDateTime::fromSecsSinceEpoch(time); break; } @@ -2006,7 +2006,7 @@ bool deployToLocalTmp(Options *options, QFileInfo fileInfo(options->qtInstallDirectory + QLatin1Char('/') + qtDependency); // Make sure precision is the same as what we get from Android - QDateTime sourceModified = QDateTime::fromTime_t(fileInfo.lastModified().toTime_t()); + QDateTime sourceModified = QDateTime::fromSecsSinceEpoch(fileInfo.lastModified().toSecsSinceEpoch()); if (options->remoteModificationDate.isNull() || options->remoteModificationDate < sourceModified) { if (!copyFileIfNewer(options->qtInstallDirectory + QLatin1Char('/') + qtDependency, diff --git a/src/assistant/3rdparty/clucene/LICENSES.txt b/src/assistant/3rdparty/clucene/LICENSES.txt new file mode 100644 index 000000000..3459edb5f --- /dev/null +++ b/src/assistant/3rdparty/clucene/LICENSES.txt @@ -0,0 +1,705 @@ +The CLucene Core Library uses a dual license strategy for the source code. +These licenses are the GNU Lesser General Public License (LGPL) and the Apache +License (Version 2.0). Users can choose the license they wish to distribute +their software under. This means that you do not need to abide by *both* +licenses, but rather than you can choose the license which most suits your +needs. + +To rephrase this and to make it perfectly clear: +CLucene is distributed under the GNU Lesser General Public License (LGPL) + *or* +the Apache License, Version 2.0 + +However, we are an open source project, and we encourage users to use the LGPL +license and participate fully in the free software community. Dual licensing +of the CLucene source code provides open and free access to the technology both +for the GPL community and for other developers or companies that cannot use the +GPL. + +You can freely modify, extend, and improve the CLucene source code. The only +question is whether or not you must provide the source code and contribute +modifications to the community. The GNU and Apache licenses allow different +ranges of flexibility in this regard, but in the end, regardless of the license +used, we highly recommend that you submit any bugs, incompatibilities or +added features. + + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 + diff --git a/src/assistant/3rdparty/clucene/qt_attribution.json b/src/assistant/3rdparty/clucene/qt_attribution.json new file mode 100644 index 000000000..8b2430b05 --- /dev/null +++ b/src/assistant/3rdparty/clucene/qt_attribution.json @@ -0,0 +1,22 @@ +{ + "Id": "clucene", + "Name": "Clucene Core Library", + "QDocModule": "qthelp", + "QtUsage": "Used in the Qt Help module and in Qt Assistant.", + + "Description": "CLucene is a C++ port of Lucene. It is a high-performance, full- featured text search engine written in C++. CLucene is faster than lucene as it is written in C++.", + "Homepage": "http://clucene.sourceforge.net/", + "License": "GNU Lesser General Public License v2.1 only or Apache License, Version 2.0", + "LicenseId": "(LGPL-2.1 OR Apache-2.0)", + "LicenseFile" : "LICENSES.txt", + "Copyright": "Copyright (C) 1991, 1999 Free Software Foundation, Inc. +Copyright (C) 1999 Tom Tromey +Copyright (C) 2000 Red Hat, Inc. +Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +Copyright (C) 2003-2006 Jos van den Oever +Copyright (C) 2003-2006 Matt J. Weinstein +Copyright (C) 2003-2006 The Apache Software Foundation +Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info> +Copyright (C) 2015 The Qt Company Ltd. +" +} diff --git a/src/assistant/3rdparty/clucene/src/CLucene/store/FSDirectory.cpp b/src/assistant/3rdparty/clucene/src/CLucene/store/FSDirectory.cpp index 1e2f04d59..c2bdf0dd8 100644 --- a/src/assistant/3rdparty/clucene/src/CLucene/store/FSDirectory.cpp +++ b/src/assistant/3rdparty/clucene/src/CLucene/store/FSDirectory.cpp @@ -511,14 +511,14 @@ int64_t FSDirectory::fileModified(const QString& name) const CND_PRECONDITION(!directory.isEmpty(), "directory is not open"); QFileInfo fInfo(directory + QDir::separator() + name); - return fInfo.lastModified().toTime_t(); + return fInfo.lastModified().toSecsSinceEpoch(); } //static int64_t FSDirectory::fileModified(const QString& dir, const QString& name) { QFileInfo fInfo(dir + QDir::separator() + name); - return fInfo.lastModified().toTime_t(); + return fInfo.lastModified().toSecsSinceEpoch(); } void FSDirectory::touchFile(const QString& name) diff --git a/src/assistant/assistant/assistant.pro b/src/assistant/assistant/assistant.pro index ef5c59587..c8fb21f1c 100644 --- a/src/assistant/assistant/assistant.pro +++ b/src/assistant/assistant/assistant.pro @@ -103,7 +103,7 @@ RESOURCES += assistant.qrc \ assistant_images.qrc win32 { - !wince*:LIBS += -lshell32 + LIBS += -lshell32 RC_FILE = assistant.rc } diff --git a/src/assistant/assistant/qtdocinstaller.cpp b/src/assistant/assistant/qtdocinstaller.cpp index abe26ca09..7a0ef5081 100644 --- a/src/assistant/assistant/qtdocinstaller.cpp +++ b/src/assistant/assistant/qtdocinstaller.cpp @@ -99,7 +99,7 @@ bool QtDocInstaller::installDoc(const DocInfo &docInfo) foreach (const QString &f, m_qchFiles) { if (f.startsWith(component)) { QFileInfo fi(m_qchDir.absolutePath() + QDir::separator() + f); - if (dt.isValid() && fi.lastModified().toTime_t() == dt.toTime_t() + if (dt.isValid() && fi.lastModified().toSecsSinceEpoch() == dt.toSecsSinceEpoch() && qchFile == fi.absoluteFilePath()) return false; emit registerDocumentation(component, fi.absoluteFilePath()); diff --git a/src/assistant/assistant/stdinlistener_win.cpp b/src/assistant/assistant/stdinlistener_win.cpp index ec893eab6..8324adb28 100644 --- a/src/assistant/assistant/stdinlistener_win.cpp +++ b/src/assistant/assistant/stdinlistener_win.cpp @@ -51,11 +51,9 @@ void StdInListener::run() bool ok = true; char chBuf[4096]; DWORD dwRead; + HANDLE hStdinDup; -#ifndef Q_OS_WINCE - HANDLE hStdin, hStdinDup; - - hStdin = GetStdHandle(STD_INPUT_HANDLE); + const HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); if (hStdin == INVALID_HANDLE_VALUE) return; @@ -64,10 +62,6 @@ void StdInListener::run() 0, false, DUPLICATE_SAME_ACCESS); CloseHandle(hStdin); -#else - HANDLE hStdinDup; - hStdinDup = stdin; -#endif while (ok) { ok = ReadFile(hStdinDup, chBuf, sizeof(chBuf), &dwRead, NULL); diff --git a/src/assistant/help/doc/qthelp.qdocconf b/src/assistant/help/doc/qthelp.qdocconf index 0b4223e93..05f34e9f3 100644 --- a/src/assistant/help/doc/qthelp.qdocconf +++ b/src/assistant/help/doc/qthelp.qdocconf @@ -29,7 +29,7 @@ depends += qtdoc qtcore qtassistant qtwidgets qmake headerdirs += .. -sourcedirs = .. +sourcedirs += .. exampledirs = ../../../../examples/help \ snippets diff --git a/src/assistant/help/doc/src/qthelp-index.qdoc b/src/assistant/help/doc/src/qthelp-index.qdoc index 732f85c65..27046abcb 100644 --- a/src/assistant/help/doc/src/qthelp-index.qdoc +++ b/src/assistant/help/doc/src/qthelp-index.qdoc @@ -58,36 +58,15 @@ \section1 License Information + Qt Core is available under commercial licenses from \l{The Qt Company}. + In addition, it is available under the + \l{GNU Lesser General Public License, version 3}, or + the \l{GNU General Public License, version 2}. + See \l{Qt Licensing} for further details. + Qt Help uses the CLucene indexing library to provide full-text searching capabilities for Qt Assistant and applications that use Qt Help features. + CLucene is available under GPL v2.1 \e{or} Apache License, Version 2.0. - Developers using the \l{Qt Commercial License} who wish to distribute - applications that use the Qt Help features need to be aware of their - obligations under the GNU Lesser General Public License (LGPL). - - Developers using the Open Source Edition can choose to redistribute - the module under the appropriate version of the GNU LGPL; version 2.1 - for applications and libraries licensed under the GNU GPL version 2, - or version 3 for applications and libraries licensed under the GNU - GPL version 3. - - \legalese - Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team \BR - Changes are Copyright (C) 2016 The Qt Company Ltd. - - 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 - \endlegalese - + \generatelist{groupsbymodule attributions-qthelp} */ diff --git a/src/assistant/help/qhelpsearchengine.cpp b/src/assistant/help/qhelpsearchengine.cpp index 183945c47..deae8136b 100644 --- a/src/assistant/help/qhelpsearchengine.cpp +++ b/src/assistant/help/qhelpsearchengine.cpp @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE #if defined(QT_CLUCENE_SUPPORT) using namespace fulltextsearch::clucene; #else - using namespace fulltextsearch::std; + using namespace fulltextsearch::qt; #endif class QHelpSearchEnginePrivate : public QObject diff --git a/src/assistant/help/qhelpsearchindexreader_default.cpp b/src/assistant/help/qhelpsearchindexreader_default.cpp index 212a48e42..6bc0ebaf1 100644 --- a/src/assistant/help/qhelpsearchindexreader_default.cpp +++ b/src/assistant/help/qhelpsearchindexreader_default.cpp @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE namespace fulltextsearch { -namespace std { +namespace qt { namespace { QStringList split( const QString &str ) diff --git a/src/assistant/help/qhelpsearchindexreader_default_p.h b/src/assistant/help/qhelpsearchindexreader_default_p.h index 7b3e4d32a..c4f391d61 100644 --- a/src/assistant/help/qhelpsearchindexreader_default_p.h +++ b/src/assistant/help/qhelpsearchindexreader_default_p.h @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE namespace fulltextsearch { -namespace std { +namespace qt { class Reader { diff --git a/src/assistant/help/qhelpsearchindexwriter_default.cpp b/src/assistant/help/qhelpsearchindexwriter_default.cpp index fa0930797..f7018ec95 100644 --- a/src/assistant/help/qhelpsearchindexwriter_default.cpp +++ b/src/assistant/help/qhelpsearchindexwriter_default.cpp @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE namespace fulltextsearch { -namespace std { +namespace qt { Writer::Writer(const QString &path) : indexPath(path) diff --git a/src/assistant/help/qhelpsearchindexwriter_default_p.h b/src/assistant/help/qhelpsearchindexwriter_default_p.h index 64934c895..ec237709e 100644 --- a/src/assistant/help/qhelpsearchindexwriter_default_p.h +++ b/src/assistant/help/qhelpsearchindexwriter_default_p.h @@ -64,7 +64,7 @@ QT_BEGIN_NAMESPACE namespace fulltextsearch { -namespace std { +namespace qt { class Writer { diff --git a/src/designer/src/components/formeditor/formeditor.pri b/src/designer/src/components/formeditor/formeditor.pri index 6b5156157..7e4afd021 100644 --- a/src/designer/src/components/formeditor/formeditor.pri +++ b/src/designer/src/components/formeditor/formeditor.pri @@ -8,7 +8,6 @@ FORMS += $$PWD/deviceprofiledialog.ui \ $$PWD/templateoptionspage.ui HEADERS += $$PWD/qdesigner_resource.h \ - $$PWD/qdesignerundostack.h \ $$PWD/formwindow.h \ $$PWD/formwindow_widgetstack.h \ $$PWD/formwindow_dnditem.h \ @@ -38,7 +37,6 @@ HEADERS += $$PWD/qdesigner_resource.h \ $$PWD/templateoptionspage.h SOURCES += $$PWD/qdesigner_resource.cpp \ - $$PWD/qdesignerundostack.cpp \ $$PWD/formwindow.cpp \ $$PWD/formwindow_widgetstack.cpp \ $$PWD/formwindow_dnditem.cpp \ diff --git a/src/designer/src/components/formeditor/formeditor_optionspage.cpp b/src/designer/src/components/formeditor/formeditor_optionspage.cpp index 028a9ed4d..72bd26b16 100644 --- a/src/designer/src/components/formeditor/formeditor_optionspage.cpp +++ b/src/designer/src/components/formeditor/formeditor_optionspage.cpp @@ -35,6 +35,7 @@ #include "previewconfigurationwidget_p.h" #include "shared_settings_p.h" #include "zoomwidget_p.h" +#include <private/actioneditor_p.h> // SDK #include <QtDesigner/QDesignerFormEditorInterface> @@ -128,10 +129,28 @@ QWidget *FormEditorOptionsPage::createPage(QWidget *parent) m_defaultGridConf->setTitle(QCoreApplication::translate("FormEditorOptionsPage", "Default Grid")); m_defaultGridConf->setGrid(settings.defaultGrid()); + const QString namingTitle = + QCoreApplication::translate("FormEditorOptionsPage", "Object Naming Convention"); + QGroupBox *namingGroupBox = new QGroupBox(namingTitle); + const QString namingToolTip = + QCoreApplication::translate("FormEditorOptionsPage", + "Naming convention used for generating action object names from their text"); + namingGroupBox->setToolTip(namingToolTip); + QHBoxLayout *namingHLayout = new QHBoxLayout(namingGroupBox); + m_namingComboBox = new QComboBox; + m_namingComboBox->setToolTip(namingToolTip); + QStringList items; // matching ActionEditor::NamingMode + items << QCoreApplication::translate("FormEditorOptionsPage", "Camel Case") + << QCoreApplication::translate("FormEditorOptionsPage", "Underscore"); + m_namingComboBox->addItems(items); + m_namingComboBox->setCurrentIndex(settings.objectNamingMode()); + namingHLayout->addWidget(m_namingComboBox.data()); + QVBoxLayout *optionsVLayout = new QVBoxLayout(); optionsVLayout->addWidget(m_defaultGridConf); optionsVLayout->addWidget(m_previewConf); optionsVLayout->addWidget(m_zoomSettingsWidget); + optionsVLayout->addWidget(namingGroupBox); optionsVLayout->addStretch(1); // Outer layout to give it horizontal stretch @@ -167,6 +186,13 @@ void FormEditorOptionsPage::apply() if (m_zoomSettingsWidget) m_zoomSettingsWidget->toSettings(settings); + + if (m_namingComboBox) { + const ObjectNamingMode namingMode + = static_cast<ObjectNamingMode>(m_namingComboBox->currentIndex()); + settings.setObjectNamingMode(namingMode); + ActionEditor::setObjectNamingMode(namingMode); + } } void FormEditorOptionsPage::finish() diff --git a/src/designer/src/components/formeditor/formeditor_optionspage.h b/src/designer/src/components/formeditor/formeditor_optionspage.h index 694b1cefc..53788ae41 100644 --- a/src/designer/src/components/formeditor/formeditor_optionspage.h +++ b/src/designer/src/components/formeditor/formeditor_optionspage.h @@ -34,6 +34,7 @@ QT_BEGIN_NAMESPACE +class QComboBox; class QDesignerFormEditorInterface; namespace qdesigner_internal { @@ -57,6 +58,7 @@ private: QPointer<PreviewConfigurationWidget> m_previewConf; QPointer<GridPanel> m_defaultGridConf; QPointer<ZoomSettingsWidget> m_zoomSettingsWidget; + QPointer<QComboBox> m_namingComboBox; }; } // namespace qdesigner_internal diff --git a/src/designer/src/components/formeditor/formwindow.cpp b/src/designer/src/components/formeditor/formwindow.cpp index ba6712103..162f5d0e3 100644 --- a/src/designer/src/components/formeditor/formwindow.cpp +++ b/src/designer/src/components/formeditor/formwindow.cpp @@ -384,7 +384,7 @@ void FormWindow::setCursorToAll(const QCursor &c, QWidget *start) void FormWindow::init() { if (FormWindowManager *manager = qobject_cast<FormWindowManager*> (core()->formWindowManager())) { - manager->undoGroup()->addStack(m_undoStack.qundoStack()); + manager->undoGroup()->addStack(&m_undoStack); } m_blockSelectionChanged = false; @@ -417,9 +417,9 @@ void FormWindow::init() m_mainContainer = 0; m_currentWidget = 0; - connect(&m_undoStack, &QDesignerUndoStack::changed, + connect(&m_undoStack, &QUndoStack::cleanChanged, this, &QDesignerFormWindowInterface::changed); - connect(&m_undoStack, &QDesignerUndoStack::changed, + connect(&m_undoStack, &QUndoStack::cleanChanged, this, &FormWindow::checkSelection); core()->metaDataBase()->add(this); @@ -2439,12 +2439,15 @@ FormWindow *FormWindow::findFormWindow(QWidget *w) bool FormWindow::isDirty() const { - return m_undoStack.isDirty(); + return !m_undoStack.isClean(); } void FormWindow::setDirty(bool dirty) { - m_undoStack.setDirty(dirty); + if (dirty) + m_undoStack.resetClean(); + else + m_undoStack.setClean(); } QWidget *FormWindow::containerAt(const QPoint &pos) @@ -2979,7 +2982,7 @@ QWidget *FormWindow::formContainer() const QUndoStack *FormWindow::commandHistory() const { - return const_cast<QDesignerUndoStack &>(m_undoStack).qundoStack(); + return &const_cast<QUndoStack &>(m_undoStack); } } // namespace diff --git a/src/designer/src/components/formeditor/formwindow.h b/src/designer/src/components/formeditor/formwindow.h index 9fd3e2cd4..c577fe1ab 100644 --- a/src/designer/src/components/formeditor/formwindow.h +++ b/src/designer/src/components/formeditor/formwindow.h @@ -30,10 +30,10 @@ #define FORMWINDOW_H #include "formeditor_global.h" -#include "qdesignerundostack.h" #include <formwindowbase_p.h> // Qt +#include <QtWidgets/QUndoStack> #include <QtCore/QHash> #include <QtCore/QList> #include <QtCore/QMap> @@ -325,7 +325,7 @@ private: QPoint m_startPos; - QDesignerUndoStack m_undoStack; + QUndoStack m_undoStack; QString m_fileName; diff --git a/src/designer/src/components/formeditor/formwindowsettings.cpp b/src/designer/src/components/formeditor/formwindowsettings.cpp index c13161a0e..3b82d0b86 100644 --- a/src/designer/src/components/formeditor/formwindowsettings.cpp +++ b/src/designer/src/components/formeditor/formwindowsettings.cpp @@ -43,18 +43,16 @@ namespace qdesigner_internal { // Data structure containing form dialog data providing comparison struct FormWindowData { - FormWindowData(); - bool equals(const FormWindowData&) const; void fromFormWindow(FormWindowBase* fw); void applyToFormWindow(FormWindowBase* fw) const; - bool layoutDefaultEnabled; - int defaultMargin; - int defaultSpacing; + bool layoutDefaultEnabled{false}; + int defaultMargin{0}; + int defaultSpacing{0}; - bool layoutFunctionsEnabled; + bool layoutFunctionsEnabled{false}; QString marginFunction; QString spacingFunction; @@ -64,7 +62,7 @@ struct FormWindowData { QStringList includeHints; - bool hasFormGrid; + bool hasFormGrid{false}; Grid grid; }; @@ -81,15 +79,6 @@ QDebug operator<<(QDebug str, const FormWindowData &d) return str; } -FormWindowData::FormWindowData() : - layoutDefaultEnabled(false), - defaultMargin(0), - defaultSpacing(0), - layoutFunctionsEnabled(false), - hasFormGrid(false) -{ -} - bool FormWindowData::equals(const FormWindowData &rhs) const { return layoutDefaultEnabled == rhs.layoutDefaultEnabled && diff --git a/src/designer/src/components/formeditor/itemview_propertysheet.cpp b/src/designer/src/components/formeditor/itemview_propertysheet.cpp index 417b57f5b..8f6761fe1 100644 --- a/src/designer/src/components/formeditor/itemview_propertysheet.cpp +++ b/src/designer/src/components/formeditor/itemview_propertysheet.cpp @@ -39,12 +39,12 @@ QT_BEGIN_NAMESPACE namespace qdesigner_internal { struct Property { - Property() : m_sheet(0),m_id(-1) {} + Property() = default; Property(QDesignerPropertySheetExtension *sheet, int id) : m_sheet(sheet), m_id(id) {} - QDesignerPropertySheetExtension *m_sheet; - int m_id; + QDesignerPropertySheetExtension *m_sheet{nullptr}; + int m_id{-1}; }; typedef QMap<int, Property> FakePropertyMap; diff --git a/src/designer/src/components/formeditor/qdesignerundostack.cpp b/src/designer/src/components/formeditor/qdesignerundostack.cpp deleted file mode 100644 index 5e6f13581..000000000 --- a/src/designer/src/components/formeditor/qdesignerundostack.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Designer of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ - -#include "qdesignerundostack.h" - -#include <QtWidgets/QUndoStack> -#include <QtWidgets/QUndoCommand> - -QT_BEGIN_NAMESPACE - -namespace qdesigner_internal { - -QDesignerUndoStack::QDesignerUndoStack(QObject *parent) : - QObject(parent), - m_undoStack(new QUndoStack), - m_fakeDirty(false) -{ - connect(m_undoStack, &QUndoStack::indexChanged, this, &QDesignerUndoStack::changed); -} - -QDesignerUndoStack::~QDesignerUndoStack() -{ // QUndoStack is managed by the QUndoGroup -} - -void QDesignerUndoStack::clear() -{ - m_fakeDirty = false; - m_undoStack->clear(); -} - -void QDesignerUndoStack::push(QUndoCommand * cmd) -{ - m_undoStack->push(cmd); -} - -void QDesignerUndoStack::beginMacro(const QString &text) -{ - m_undoStack->beginMacro(text); -} - -void QDesignerUndoStack::endMacro() -{ - m_undoStack->endMacro(); -} - -int QDesignerUndoStack::index() const -{ - return m_undoStack->index(); -} - -const QUndoStack *QDesignerUndoStack::qundoStack() const -{ - return m_undoStack; -} -QUndoStack *QDesignerUndoStack::qundoStack() -{ - return m_undoStack; -} - -bool QDesignerUndoStack::isDirty() const -{ - return m_fakeDirty || !m_undoStack->isClean(); -} - -void QDesignerUndoStack::setDirty(bool v) -{ - if (isDirty() == v) - return; - if (v) { - m_fakeDirty = true; - emit changed(); - } else { - m_fakeDirty = false; - m_undoStack->setClean(); - } -} - -} // namespace qdesigner_internal - -QT_END_NAMESPACE diff --git a/src/designer/src/components/propertyeditor/designerpropertymanager.h b/src/designer/src/components/propertyeditor/designerpropertymanager.h index d55d1ce0e..582242a4a 100644 --- a/src/designer/src/components/propertyeditor/designerpropertymanager.h +++ b/src/designer/src/components/propertyeditor/designerpropertymanager.h @@ -171,8 +171,7 @@ private: int bitCount(int mask) const; struct FlagData { - FlagData() : val(0) {} - uint val; + uint val{0}; DesignerFlagList flags; QList<uint> values; }; diff --git a/src/designer/src/components/widgetbox/widgetboxcategorylistview.cpp b/src/designer/src/components/widgetbox/widgetboxcategorylistview.cpp index 3c644cd3c..bd00bc2c7 100644 --- a/src/designer/src/components/widgetbox/widgetboxcategorylistview.cpp +++ b/src/designer/src/components/widgetbox/widgetboxcategorylistview.cpp @@ -74,7 +74,7 @@ namespace qdesigner_internal { // Entry of the model list struct WidgetBoxCategoryEntry { - WidgetBoxCategoryEntry(); + WidgetBoxCategoryEntry() = default; explicit WidgetBoxCategoryEntry(const QDesignerWidgetBoxInterface::Widget &widget, const QString &filter, const QIcon &icon, @@ -85,15 +85,9 @@ struct WidgetBoxCategoryEntry { QString whatsThis; QString filter; QIcon icon; - bool editable; + bool editable{false}; }; - -WidgetBoxCategoryEntry::WidgetBoxCategoryEntry() : - editable(false) -{ -} - WidgetBoxCategoryEntry::WidgetBoxCategoryEntry(const QDesignerWidgetBoxInterface::Widget &w, const QString &filterIn, const QIcon &i, bool e) : diff --git a/src/designer/src/designer/qdesigner.cpp b/src/designer/src/designer/qdesigner.cpp index 593f590ab..d4b9b7552 100644 --- a/src/designer/src/designer/qdesigner.cpp +++ b/src/designer/src/designer/qdesigner.cpp @@ -162,15 +162,11 @@ static void showHelp(QCommandLineParser &parser, const QString &errorMessage = Q struct Options { - Options() - : resourceDir(QLibraryInfo::location(QLibraryInfo::TranslationsPath)) - , server(false), clientPort(0), enableInternalDynamicProperties(false) {} - QStringList files; - QString resourceDir; - bool server; - quint16 clientPort; - bool enableInternalDynamicProperties; + QString resourceDir{QLibraryInfo::location(QLibraryInfo::TranslationsPath)}; + bool server{false}; + quint16 clientPort{0}; + bool enableInternalDynamicProperties{false}; }; static inline QDesigner::ParseArgumentsResult diff --git a/src/designer/src/designer/qdesigner_appearanceoptions.cpp b/src/designer/src/designer/qdesigner_appearanceoptions.cpp index d1dcaa3f2..33d42ad2b 100644 --- a/src/designer/src/designer/qdesigner_appearanceoptions.cpp +++ b/src/designer/src/designer/qdesigner_appearanceoptions.cpp @@ -39,11 +39,6 @@ QT_BEGIN_NAMESPACE // ---------------- AppearanceOptions -AppearanceOptions::AppearanceOptions() : - uiMode(DockedMode) -{ -} - bool AppearanceOptions::equals(const AppearanceOptions &rhs) const { return uiMode == rhs.uiMode && toolWindowFontSettings == rhs.toolWindowFontSettings; diff --git a/src/designer/src/designer/qdesigner_appearanceoptions.h b/src/designer/src/designer/qdesigner_appearanceoptions.h index 219f18091..f1d1aea05 100644 --- a/src/designer/src/designer/qdesigner_appearanceoptions.h +++ b/src/designer/src/designer/qdesigner_appearanceoptions.h @@ -49,12 +49,11 @@ namespace Ui { /* AppearanceOptions data */ struct AppearanceOptions { - AppearanceOptions(); bool equals(const AppearanceOptions&) const; void toSettings(QDesignerSettings &) const; void fromSettings(const QDesignerSettings &); - UIMode uiMode; + UIMode uiMode{DockedMode}; ToolWindowFontSettings toolWindowFontSettings; }; diff --git a/src/designer/src/designer/qdesigner_toolwindow.cpp b/src/designer/src/designer/qdesigner_toolwindow.cpp index 1c03065ca..3655fd64e 100644 --- a/src/designer/src/designer/qdesigner_toolwindow.cpp +++ b/src/designer/src/designer/qdesigner_toolwindow.cpp @@ -48,12 +48,6 @@ enum { debugToolWindow = 0 }; QT_BEGIN_NAMESPACE // ---------------- QDesignerToolWindowFontSettings -ToolWindowFontSettings::ToolWindowFontSettings() : - m_writingSystem(QFontDatabase::Any), - m_useFont(false) -{ -} - bool ToolWindowFontSettings::equals(const ToolWindowFontSettings &rhs) const { return m_useFont == rhs.m_useFont && diff --git a/src/designer/src/designer/qdesigner_toolwindow.h b/src/designer/src/designer/qdesigner_toolwindow.h index 2d1490f16..741e8a6bd 100644 --- a/src/designer/src/designer/qdesigner_toolwindow.h +++ b/src/designer/src/designer/qdesigner_toolwindow.h @@ -38,12 +38,11 @@ QT_BEGIN_NAMESPACE struct ToolWindowFontSettings { - ToolWindowFontSettings(); bool equals(const ToolWindowFontSettings &) const; QFont m_font; - QFontDatabase::WritingSystem m_writingSystem; - bool m_useFont; + QFontDatabase::WritingSystem m_writingSystem{QFontDatabase::Any}; + bool m_useFont{false}; }; inline bool operator==(const ToolWindowFontSettings &tw1, const ToolWindowFontSettings &tw2) diff --git a/src/designer/src/lib/sdk/abstractformeditor.cpp b/src/designer/src/lib/sdk/abstractformeditor.cpp index 21d58844e..54a83fa34 100644 --- a/src/designer/src/lib/sdk/abstractformeditor.cpp +++ b/src/designer/src/lib/sdk/abstractformeditor.cpp @@ -43,6 +43,7 @@ #include <QtDesigner/QDesignerActionEditorInterface> #include <QtDesigner/QDesignerWidgetBoxInterface> +#include <actioneditor_p.h> #include <pluginmanager_p.h> #include <qtresourcemodel_p.h> #include <qtgradientmanager.h> @@ -514,6 +515,7 @@ void QDesignerFormEditorInterface::setSettingsManager(QDesignerSettingsInterface // initializations. const qdesigner_internal::QDesignerSharedSettings settings(this); qdesigner_internal::FormWindowBase::setDefaultDesignerGrid(settings.defaultGrid()); + qdesigner_internal::ActionEditor::setObjectNamingMode(settings.objectNamingMode()); } /*! diff --git a/src/designer/src/lib/shared/actioneditor.cpp b/src/designer/src/lib/shared/actioneditor.cpp index bbbe2a55b..b33225159 100644 --- a/src/designer/src/lib/shared/actioneditor.cpp +++ b/src/designer/src/lib/shared/actioneditor.cpp @@ -64,7 +64,7 @@ #include <QtGui/QContextMenuEvent> #include <QtCore/QItemSelection> -#include <QtCore/QRegExp> +#include <QtCore/QRegularExpression> #include <QtCore/QDebug> #include <QtCore/QBuffer> @@ -101,6 +101,8 @@ public: }; //-------- ActionEditor +ObjectNamingMode ActionEditor::m_objectNamingMode = Underscore; // fixme Qt 6: CamelCase + ActionEditor::ActionEditor(QDesignerFormEditorInterface *core, QWidget *parent, Qt::WindowFlags flags) : QDesignerActionEditorInterface(parent, flags), m_core(core), @@ -648,21 +650,61 @@ void ActionEditor::slotDelete() deleteActions(fw, selection); } +// UnderScore: "Open file" -> actionOpen_file +static QString underscore(QString text) +{ + const QString underscore = QString(QLatin1Char('_')); + static const QRegularExpression nonAsciiPattern(QStringLiteral("[^a-zA-Z_0-9]")); + Q_ASSERT(nonAsciiPattern.isValid()); + text.replace(nonAsciiPattern, underscore); + static const QRegularExpression multipleSpacePattern(QStringLiteral("__*")); + Q_ASSERT(multipleSpacePattern.isValid()); + text.replace(multipleSpacePattern, underscore); + if (text.endsWith(underscore.at(0))) + text.chop(1); + return text; +} + +// CamelCase: "Open file" -> actionOpenFile, ignoring non-ASCII letters. + +enum CharacterCategory { OtherCharacter, DigitOrAsciiLetter, NonAsciiLetter }; + +static inline CharacterCategory category(QChar c) +{ + if (c.isDigit()) + return DigitOrAsciiLetter; + if (c.isLetter()) { + const ushort uc = c.unicode(); + return (uc >= 'a' && uc <= 'z') || (uc >= 'A' && uc <= 'Z') + ? DigitOrAsciiLetter : NonAsciiLetter; + } + return OtherCharacter; +} + +static QString camelCase(const QString &text) +{ + QString result; + result.reserve(text.size()); + bool lastCharAccepted = false; + for (QChar c : text) { + const CharacterCategory cat = category(c); + if (cat != NonAsciiLetter) { + const bool acceptable = cat == DigitOrAsciiLetter; + if (acceptable) + result.append(lastCharAccepted ? c : c.toUpper()); // New word starts + lastCharAccepted = acceptable; + } + } + return result; +} + QString ActionEditor::actionTextToName(const QString &text, const QString &prefix) { QString name = text; if (name.isEmpty()) return QString(); + return prefix + (m_objectNamingMode == CamelCase ? camelCase(text) : underscore(text)); - name[0] = name.at(0).toUpper(); - name.prepend(prefix); - const QString underscore = QString(QLatin1Char('_')); - name.replace(QRegExp(QString(QStringLiteral("[^a-zA-Z_0-9]"))), underscore); - name.replace(QRegExp(QStringLiteral("__*")), underscore); - if (name.endsWith(underscore.at(0))) - name.truncate(name.size() - 1); - - return name; } void ActionEditor::resourceImageDropped(const QString &path, QAction *action) diff --git a/src/designer/src/lib/shared/actioneditor_p.h b/src/designer/src/lib/shared/actioneditor_p.h index 95cf0221c..d97e2ef00 100644 --- a/src/designer/src/lib/shared/actioneditor_p.h +++ b/src/designer/src/lib/shared/actioneditor_p.h @@ -41,6 +41,7 @@ #define ACTIONEDITOR_H #include "shared_global_p.h" +#include "shared_enums_p.h" #include <QtDesigner/QDesignerActionEditorInterface> #include <QtCore/QPointer> @@ -82,7 +83,11 @@ public: void manageAction(QAction *action) Q_DECL_OVERRIDE; void unmanageAction(QAction *action) Q_DECL_OVERRIDE; - static QString actionTextToName(const QString &text, const QString &prefix = QLatin1String("action")); + static ObjectNamingMode objectNamingMode() { return m_objectNamingMode; } + static void setObjectNamingMode(ObjectNamingMode n) { m_objectNamingMode = n; } + + static QString actionTextToName(const QString &text, + const QString &prefix = QLatin1String("action")); // Utility to create a configure button with menu for usage on toolbars static QToolButton *createConfigureMenuButton(const QString &t, QMenu **ptrToMenu); @@ -127,6 +132,8 @@ private: void updateViewModeActions(); + static ObjectNamingMode m_objectNamingMode; + QDesignerFormEditorInterface *m_core; QPointer<QDesignerFormWindowInterface> m_formWindow; QListWidget *m_actionGroups; diff --git a/src/designer/src/lib/shared/formlayoutmenu.cpp b/src/designer/src/lib/shared/formlayoutmenu.cpp index 7890940ec..96ecf5795 100644 --- a/src/designer/src/lib/shared/formlayoutmenu.cpp +++ b/src/designer/src/lib/shared/formlayoutmenu.cpp @@ -68,13 +68,11 @@ namespace qdesigner_internal { // Struct that describes a row of controls (descriptive label and control) to // be added to a form layout. struct FormLayoutRow { - FormLayoutRow() : buddy(false) {} - QString labelName; QString labelText; QString fieldClassName; QString fieldName; - bool buddy; + bool buddy{false}; }; // A Dialog to edit a FormLayoutRow. Lets the user input a label text, label diff --git a/src/designer/src/lib/shared/formwindowbase.cpp b/src/designer/src/lib/shared/formwindowbase.cpp index e702d777a..d8f422a0a 100644 --- a/src/designer/src/lib/shared/formwindowbase.cpp +++ b/src/designer/src/lib/shared/formwindowbase.cpp @@ -47,6 +47,7 @@ #include <QtCore/qdebug.h> #include <QtCore/QList> +#include <QtCore/QSet> #include <QtCore/QTimer> #include <QtWidgets/QMenu> #include <QtWidgets/QListWidget> @@ -112,6 +113,15 @@ FormWindowBase::FormWindowBase(QDesignerFormEditorInterface *core, QWidget *pare FormWindowBase::~FormWindowBase() { + QSet<QDesignerPropertySheet *> sheets = m_d->m_reloadableResources.keys().toSet(); + sheets |= m_d->m_reloadablePropertySheets.keys().toSet(); + + m_d->m_reloadableResources.clear(); + m_d->m_reloadablePropertySheets.clear(); + + for (QDesignerPropertySheet *sheet : sheets) + disconnectSheet(sheet); + delete m_d; } @@ -137,14 +147,17 @@ void FormWindowBase::setResourceSet(QtResourceSet *resourceSet) void FormWindowBase::addReloadableProperty(QDesignerPropertySheet *sheet, int index) { + connectSheet(sheet); m_d->m_reloadableResources[sheet][index] = true; } void FormWindowBase::removeReloadableProperty(QDesignerPropertySheet *sheet, int index) { m_d->m_reloadableResources[sheet].remove(index); - if (m_d->m_reloadableResources[sheet].count() == 0) + if (!m_d->m_reloadableResources[sheet].count()) { m_d->m_reloadableResources.remove(sheet); + disconnectSheet(sheet); + } } void FormWindowBase::addReloadablePropertySheet(QDesignerPropertySheet *sheet, QObject *object) @@ -152,13 +165,53 @@ void FormWindowBase::addReloadablePropertySheet(QDesignerPropertySheet *sheet, Q if (qobject_cast<QTreeWidget *>(object) || qobject_cast<QTableWidget *>(object) || qobject_cast<QListWidget *>(object) || - qobject_cast<QComboBox *>(object)) + qobject_cast<QComboBox *>(object)) { + connectSheet(sheet); m_d->m_reloadablePropertySheets[sheet] = object; + } } -void FormWindowBase::removeReloadablePropertySheet(QDesignerPropertySheet *sheet) +void FormWindowBase::connectSheet(QDesignerPropertySheet *sheet) { - m_d->m_reloadablePropertySheets.remove(sheet); + if (m_d->m_reloadableResources.contains(sheet) + || m_d->m_reloadablePropertySheets.contains(sheet)) { + // already connected + return; + } + connect(sheet, &QObject::destroyed, this, &FormWindowBase::sheetDestroyed); +} + +void FormWindowBase::disconnectSheet(QDesignerPropertySheet *sheet) +{ + if (m_d->m_reloadableResources.contains(sheet) + || m_d->m_reloadablePropertySheets.contains(sheet)) { + // still need to be connected + return; + } + disconnect(sheet, &QObject::destroyed, this, &FormWindowBase::sheetDestroyed); +} + +void FormWindowBase::sheetDestroyed(QObject *object) +{ + // qobject_cast<QDesignerPropertySheet *>(object) + // will fail since the destructor of QDesignerPropertySheet + // has already finished + + for (auto it = m_d->m_reloadableResources.begin(); + it != m_d->m_reloadableResources.end(); ++it) { + if (it.key() == object) { + m_d->m_reloadableResources.erase(it); + break; + } + } + + for (auto it = m_d->m_reloadablePropertySheets.begin(); + it != m_d->m_reloadablePropertySheets.end(); ++it) { + if (it.key() == object) { + m_d->m_reloadablePropertySheets.erase(it); + break; + } + } } void FormWindowBase::reloadProperties() diff --git a/src/designer/src/lib/shared/formwindowbase_p.h b/src/designer/src/lib/shared/formwindowbase_p.h index 0740e48a6..ceb8beb80 100644 --- a/src/designer/src/lib/shared/formwindowbase_p.h +++ b/src/designer/src/lib/shared/formwindowbase_p.h @@ -138,7 +138,6 @@ public: void addReloadableProperty(QDesignerPropertySheet *sheet, int index); void removeReloadableProperty(QDesignerPropertySheet *sheet, int index); void addReloadablePropertySheet(QDesignerPropertySheet *sheet, QObject *object); - void removeReloadablePropertySheet(QDesignerPropertySheet *sheet); void reloadProperties(); void emitWidgetRemoved(QWidget *w); @@ -167,9 +166,12 @@ public slots: private slots: void triggerDefaultAction(QWidget *w); + void sheetDestroyed(QObject *object); private: void syncGridFeature(); + void connectSheet(QDesignerPropertySheet *sheet); + void disconnectSheet(QDesignerPropertySheet *sheet); FormWindowBasePrivate *m_d; }; diff --git a/src/designer/src/lib/shared/newactiondialog.cpp b/src/designer/src/lib/shared/newactiondialog.cpp index 6241055ab..afddd7589 100644 --- a/src/designer/src/lib/shared/newactiondialog.cpp +++ b/src/designer/src/lib/shared/newactiondialog.cpp @@ -43,13 +43,6 @@ QT_BEGIN_NAMESPACE namespace qdesigner_internal { -// -------------------- ActionData - -ActionData::ActionData() : - checkable(false) -{ -} - // Returns a combination of ChangeMask flags unsigned ActionData::compare(const ActionData &rhs) const { diff --git a/src/designer/src/lib/shared/newactiondialog_p.h b/src/designer/src/lib/shared/newactiondialog_p.h index 23be466c8..57995dc9f 100644 --- a/src/designer/src/lib/shared/newactiondialog_p.h +++ b/src/designer/src/lib/shared/newactiondialog_p.h @@ -62,7 +62,6 @@ struct ActionData { IconChanged = 0x8, CheckableChanged = 0x10, KeysequenceChanged = 0x20 }; - ActionData(); // Returns a combination of ChangeMask flags unsigned compare(const ActionData &rhs) const; @@ -70,7 +69,7 @@ struct ActionData { QString name; QString toolTip; PropertySheetIconValue icon; - bool checkable; + bool checkable{false}; PropertySheetKeySequenceValue keysequence; }; diff --git a/src/designer/src/lib/shared/promotionmodel.cpp b/src/designer/src/lib/shared/promotionmodel.cpp index 06e7ca44c..fcda653b2 100644 --- a/src/designer/src/lib/shared/promotionmodel.cpp +++ b/src/designer/src/lib/shared/promotionmodel.cpp @@ -65,17 +65,16 @@ namespace { } // Create an editable model row for a promoted class. - StandardItemList promotedModelRow(const QDesignerWidgetDataBaseInterface *widgetDataBase, + StandardItemList promotedModelRow(QDesignerWidgetDataBaseItemInterface *baseItem, QDesignerWidgetDataBaseItemInterface *dbItem, - bool referenced = false) { - - const int index = widgetDataBase->indexOf(dbItem); + bool referenced) + { + qdesigner_internal::PromotionModel::ModelData data; + data.baseItem = baseItem; + data.promotedItem = dbItem; + data.referenced = referenced; - // Associate user data: database index and enabled flag - QVariantList userDataList; - userDataList.push_back(QVariant(index)); - userDataList.push_back(QVariant(referenced)); - const QVariant userData(userDataList); + const QVariant userData = qVariantFromValue(data); StandardItemList rc = modelRow(); // name @@ -135,7 +134,6 @@ namespace qdesigner_internal { const QSet<QString> usedPromotedClasses = m_core->promotion()->referencedPromotedClassNames(); - QDesignerWidgetDataBaseInterface *widgetDataBase = m_core->widgetDataBase(); QDesignerWidgetDataBaseItemInterface *baseClass = 0; QStandardItem *baseItem = 0; @@ -150,15 +148,15 @@ namespace qdesigner_internal { } Q_ASSERT(baseItem); // Append derived - baseItem->appendRow(promotedModelRow(widgetDataBase, it->promotedItem, usedPromotedClasses.contains(it->promotedItem->name()))); + baseItem->appendRow(promotedModelRow(it->baseItem, it->promotedItem, usedPromotedClasses.contains(it->promotedItem->name()))); } } void PromotionModel::slotItemChanged(QStandardItem * changedItem) { // Retrieve DB item - bool referenced; - QDesignerWidgetDataBaseItemInterface *dbItem = databaseItem(changedItem, &referenced); - Q_ASSERT(dbItem); + const ModelData data = modelData(changedItem); + Q_ASSERT(data.isValid()); + QDesignerWidgetDataBaseItemInterface *dbItem = data.promotedItem; // Change header or type switch (changedItem->column()) { case ClassNameColumn: @@ -176,26 +174,15 @@ namespace qdesigner_internal { } } - QDesignerWidgetDataBaseItemInterface *PromotionModel::databaseItemAt(const QModelIndex &index, bool *referenced) const { - if (const QStandardItem *item = itemFromIndex (index)) - return databaseItem(item, referenced); - - *referenced = false; - return 0; + PromotionModel::ModelData PromotionModel::modelData(const QStandardItem *item) const + { + const QVariant userData = item->data(); + return userData.canConvert<ModelData>() ? userData.value<ModelData>() : ModelData(); } - QDesignerWidgetDataBaseItemInterface *PromotionModel::databaseItem(const QStandardItem * item, bool *referenced) const { - // Decode user data associated with item. - const QVariant data = item->data(); - if (data.type() != QVariant::List) { - *referenced = false; - return 0; - } - - const QVariantList dataList = data.toList(); - const int index = dataList[0].toInt(); - *referenced = dataList[1].toBool(); - return m_core->widgetDataBase()->item(index); + PromotionModel::ModelData PromotionModel::modelData(const QModelIndex &index) const + { + return index.isValid() ? modelData(itemFromIndex(index)) : ModelData(); } QModelIndex PromotionModel::indexOfClass(const QString &className) const { diff --git a/src/designer/src/lib/shared/promotionmodel_p.h b/src/designer/src/lib/shared/promotionmodel_p.h index df3d6dd21..f06a6659b 100644 --- a/src/designer/src/lib/shared/promotionmodel_p.h +++ b/src/designer/src/lib/shared/promotionmodel_p.h @@ -41,6 +41,7 @@ #define PROMOTIONMODEL_H #include <QtGui/QStandardItemModel> +#include <QtCore/QMetaType> #include <QtCore/QSet> QT_BEGIN_NAMESPACE @@ -55,12 +56,20 @@ namespace qdesigner_internal { Q_OBJECT public: + struct ModelData { + bool isValid() const { return promotedItem != nullptr; } + + QDesignerWidgetDataBaseItemInterface *baseItem{nullptr}; + QDesignerWidgetDataBaseItemInterface *promotedItem{nullptr}; + bool referenced{false}; + }; + explicit PromotionModel(QDesignerFormEditorInterface *core); void updateFromWidgetDatabase(); - // Return item at model index or 0. - QDesignerWidgetDataBaseItemInterface *databaseItemAt(const QModelIndex &, bool *referenced) const; + ModelData modelData(const QModelIndex &index) const; + ModelData modelData(const QStandardItem *item) const; QModelIndex indexOfClass(const QString &className) const; @@ -73,8 +82,6 @@ namespace qdesigner_internal { private: void initializeHeaders(); - // Retrieve data base item of item or return 0. - QDesignerWidgetDataBaseItemInterface *databaseItem(const QStandardItem * item, bool *referenced) const; QDesignerFormEditorInterface *m_core; }; @@ -82,4 +89,6 @@ namespace qdesigner_internal { QT_END_NAMESPACE +Q_DECLARE_METATYPE(qdesigner_internal::PromotionModel::ModelData) + #endif // PROMOTIONMODEL_H diff --git a/src/designer/src/lib/shared/qdesigner_membersheet.cpp b/src/designer/src/lib/shared/qdesigner_membersheet.cpp index 00939e54b..10de9f3d4 100644 --- a/src/designer/src/lib/shared/qdesigner_membersheet.cpp +++ b/src/designer/src/lib/shared/qdesigner_membersheet.cpp @@ -69,10 +69,8 @@ public: class Info { public: - inline Info() : visible(true) {} - QString group; - bool visible; + bool visible{true}; }; typedef QHash<int, Info> InfoHash; diff --git a/src/designer/src/lib/shared/qdesigner_promotion.cpp b/src/designer/src/lib/shared/qdesigner_promotion.cpp index fabca5514..61c7675cf 100644 --- a/src/designer/src/lib/shared/qdesigner_promotion.cpp +++ b/src/designer/src/lib/shared/qdesigner_promotion.cpp @@ -116,6 +116,13 @@ namespace { } } +static void markFormsDirty(const QDesignerFormEditorInterface *core) +{ + const QDesignerFormWindowManagerInterface *fwm = core->formWindowManager(); + for (int f = 0, count = fwm->formWindowCount(); f < count; ++f) + fwm->formWindow(f)->setDirty(true); +} + namespace qdesigner_internal { QDesignerPromotion::QDesignerPromotion(QDesignerFormEditorInterface *core) : @@ -153,6 +160,7 @@ namespace qdesigner_internal { promotedItem->setExtends(baseClass); promotedItem->setIncludeFile(includeFile); widgetDataBase->append(promotedItem); + markFormsDirty(m_core); return true; } @@ -303,6 +311,7 @@ namespace qdesigner_internal { } } widgetDataBase->remove(index); + markFormsDirty(m_core); return true; } @@ -344,6 +353,7 @@ namespace qdesigner_internal { if (foundReferences) refreshObjectInspector(); + markFormsDirty(m_core); return true; } @@ -358,8 +368,10 @@ namespace qdesigner_internal { QDesignerWidgetDataBaseItemInterface *dbItem = promotedWidgetDataBaseItem(widgetDataBase, className, errorMessage); if (!dbItem) return false; - - dbItem->setIncludeFile(includeFile); + if (dbItem->includeFile() != includeFile) { + dbItem->setIncludeFile(includeFile); + markFormsDirty(m_core); + } return true; } diff --git a/src/designer/src/lib/shared/qdesigner_promotiondialog.cpp b/src/designer/src/lib/shared/qdesigner_promotiondialog.cpp index f5f96c554..cec794fb5 100644 --- a/src/designer/src/lib/shared/qdesigner_promotiondialog.cpp +++ b/src/designer/src/lib/shared/qdesigner_promotiondialog.cpp @@ -355,12 +355,11 @@ namespace qdesigner_internal { const QModelIndexList indexes = selected.indexes(); if (indexes.empty()) return 0; - - bool referenced; - QDesignerWidgetDataBaseItemInterface *dbItem = m_model->databaseItemAt(indexes.front(), &referenced); + const PromotionModel::ModelData data = m_model->modelData(indexes.constFirst()); + QDesignerWidgetDataBaseItemInterface *dbItem = data.promotedItem; if (dbItem) { - if (referenced) + if (data.referenced) flags |= Referenced; // In choose mode, can we promote to the class? if (m_mode == ModeEditChooseClass && dbItem && dbItem->isPromoted() && dbItem->extends() == m_promotableWidgetClassName) diff --git a/src/designer/src/lib/shared/qdesigner_propertysheet.cpp b/src/designer/src/lib/shared/qdesigner_propertysheet.cpp index 3caaba690..6a0910e2a 100644 --- a/src/designer/src/lib/shared/qdesigner_propertysheet.cpp +++ b/src/designer/src/lib/shared/qdesigner_propertysheet.cpp @@ -699,8 +699,6 @@ QDesignerPropertySheet::QDesignerPropertySheet(QObject *object, QObject *parent) QDesignerPropertySheet::~QDesignerPropertySheet() { - if (d->m_fwb) - d->m_fwb->removeReloadablePropertySheet(this); delete d; } @@ -1627,8 +1625,6 @@ struct QDesignerAbstractPropertySheetFactory::PropertySheetFactoryPrivate { typedef QMap<QObject*, QObject*> ExtensionMap; ExtensionMap m_extensions; - typedef QHash<QObject*, bool> ExtendedSet; - ExtendedSet m_extended; }; QDesignerAbstractPropertySheetFactory::PropertySheetFactoryPrivate::PropertySheetFactoryPrivate() : @@ -1653,30 +1649,20 @@ QDesignerAbstractPropertySheetFactory::~QDesignerAbstractPropertySheetFactory() QObject *QDesignerAbstractPropertySheetFactory::extension(QObject *object, const QString &iid) const { - typedef PropertySheetFactoryPrivate::ExtensionMap ExtensionMap; if (!object) return 0; if (iid != m_impl->m_propertySheetId && iid != m_impl->m_dynamicPropertySheetId) return 0; - ExtensionMap::iterator it = m_impl->m_extensions.find(object); - if (it == m_impl->m_extensions.end()) { - if (QObject *ext = createPropertySheet(object, const_cast<QDesignerAbstractPropertySheetFactory*>(this))) { - connect(ext, &QObject::destroyed, this, &QDesignerAbstractPropertySheetFactory::objectDestroyed); - it = m_impl->m_extensions.insert(object, ext); - } - } - - if (!m_impl->m_extended.contains(object)) { + QObject *ext = m_impl->m_extensions.value(object, 0); + if (!ext && (ext = createPropertySheet(object, const_cast<QDesignerAbstractPropertySheetFactory*>(this)))) { + connect(ext, &QObject::destroyed, this, &QDesignerAbstractPropertySheetFactory::objectDestroyed); connect(object, &QObject::destroyed, this, &QDesignerAbstractPropertySheetFactory::objectDestroyed); - m_impl->m_extended.insert(object, true); + m_impl->m_extensions.insert(object, ext); } - if (it == m_impl->m_extensions.end()) - return 0; - - return it.value(); + return ext; } void QDesignerAbstractPropertySheetFactory::objectDestroyed(QObject *object) @@ -1684,14 +1670,15 @@ void QDesignerAbstractPropertySheetFactory::objectDestroyed(QObject *object) QMutableMapIterator<QObject*, QObject*> it(m_impl->m_extensions); while (it.hasNext()) { it.next(); - - QObject *o = it.key(); - if (o == object || object == it.value()) { + if (it.key() == object || it.value() == object) { + if (it.key() == object) { + QObject *ext = it.value(); + disconnect(ext, &QObject::destroyed, this, &QDesignerAbstractPropertySheetFactory::objectDestroyed); + delete ext; + } it.remove(); } } - - m_impl->m_extended.remove(object); } QT_END_NAMESPACE diff --git a/src/designer/src/lib/shared/qdesigner_utils.cpp b/src/designer/src/lib/shared/qdesigner_utils.cpp index a95ef6acc..3d4a6bf18 100644 --- a/src/designer/src/lib/shared/qdesigner_utils.cpp +++ b/src/designer/src/lib/shared/qdesigner_utils.cpp @@ -247,10 +247,8 @@ namespace qdesigner_internal metaEnum(me) { } - PropertySheetEnumValue::PropertySheetEnumValue() : - value(0) - { - } + + PropertySheetEnumValue::PropertySheetEnumValue() = default; // ---------------- PropertySheetFlagValue PropertySheetFlagValue::PropertySheetFlagValue(int v, const DesignerMetaFlags &mf) : @@ -259,10 +257,7 @@ namespace qdesigner_internal { } - PropertySheetFlagValue::PropertySheetFlagValue() : - value(0) - { - } + PropertySheetFlagValue::PropertySheetFlagValue() = default; // ---------------- PropertySheetPixmapValue PropertySheetPixmapValue::PropertySheetPixmapValue(const QString &path) : m_path(path) diff --git a/src/designer/src/lib/shared/qdesigner_utils_p.h b/src/designer/src/lib/shared/qdesigner_utils_p.h index 766043878..af2fd5246 100644 --- a/src/designer/src/lib/shared/qdesigner_utils_p.h +++ b/src/designer/src/lib/shared/qdesigner_utils_p.h @@ -199,7 +199,7 @@ struct QDESIGNER_SHARED_EXPORT PropertySheetEnumValue PropertySheetEnumValue(int v, const DesignerMetaEnum &me); PropertySheetEnumValue(); - int value; + int value{0}; DesignerMetaEnum metaEnum; }; @@ -210,7 +210,7 @@ struct QDESIGNER_SHARED_EXPORT PropertySheetFlagValue PropertySheetFlagValue(int v, const DesignerMetaFlags &mf); PropertySheetFlagValue(); - int value; + int value{0}; DesignerMetaFlags metaFlags; }; diff --git a/src/designer/src/lib/shared/shared_enums_p.h b/src/designer/src/lib/shared/shared_enums_p.h index cf17bf703..d9c3dc007 100644 --- a/src/designer/src/lib/shared/shared_enums_p.h +++ b/src/designer/src/lib/shared/shared_enums_p.h @@ -79,6 +79,7 @@ namespace qdesigner_internal { ItemFlagsShadowRole = 0x13370551 }; + enum ObjectNamingMode { CamelCase, Underscore }; } QT_END_NAMESPACE diff --git a/src/designer/src/lib/shared/shared_settings.cpp b/src/designer/src/lib/shared/shared_settings.cpp index 82909df70..9d3730244 100644 --- a/src/designer/src/lib/shared/shared_settings.cpp +++ b/src/designer/src/lib/shared/shared_settings.cpp @@ -31,6 +31,8 @@ #include "previewmanager_p.h" #include "qdesigner_utils_p.h" +#include <actioneditor_p.h> + #include <QtDesigner/QDesignerFormEditorInterface> #include <QtDesigner/QDesignerSettingsInterface> @@ -54,6 +56,9 @@ static const char *deviceProfilesKey = "DeviceProfiles"; static const char *formTemplatePathsKey = "FormTemplatePaths"; static const char *formTemplateKey = "FormTemplate"; static const char *newFormSizeKey = "NewFormSize"; +static inline QString namingModeKey() { return QStringLiteral("naming"); } +static inline QString underScoreNamingMode() { return QStringLiteral("underscore"); } +static inline QString camelCaseNamingMode() { return QStringLiteral("camelcase"); } using namespace qdesigner_internal; @@ -226,6 +231,20 @@ void QDesignerSharedSettings::setZoom(int z) m_settings->setValue(QLatin1String(zoomKey), QVariant(z)); } +ObjectNamingMode QDesignerSharedSettings::objectNamingMode() const +{ + const QString value = m_settings->value(namingModeKey()).toString(); + return value == camelCaseNamingMode() + ? qdesigner_internal::CamelCase : qdesigner_internal::Underscore; +} + +void QDesignerSharedSettings::setObjectNamingMode(ObjectNamingMode n) +{ + const QString value = n == qdesigner_internal::CamelCase + ? camelCaseNamingMode() : underScoreNamingMode(); + m_settings->setValue(namingModeKey(), QVariant(value)); +} + bool QDesignerSharedSettings::zoomEnabled() const { return m_settings->value(QLatin1String(zoomEnabledKey), false).toBool(); diff --git a/src/designer/src/lib/shared/shared_settings_p.h b/src/designer/src/lib/shared/shared_settings_p.h index 2ee0c7dc7..3a2fafd9a 100644 --- a/src/designer/src/lib/shared/shared_settings_p.h +++ b/src/designer/src/lib/shared/shared_settings_p.h @@ -41,6 +41,7 @@ #define SHARED_SETTINGS_H #include "shared_global_p.h" +#include "shared_enums_p.h" #include "deviceprofile_p.h" #include <QtCore/qglobal.h> @@ -103,6 +104,10 @@ public: int zoom() const; void setZoom(int z); + // Object naming convention (ActionEditor) + ObjectNamingMode objectNamingMode() const; + void setObjectNamingMode(ObjectNamingMode n); + // Embedded Design DeviceProfile currentDeviceProfile() const; void setCurrentDeviceProfileIndex(int i); diff --git a/src/kmap2qmap/kmap2qmap.pro b/src/kmap2qmap/kmap2qmap.pro index 7ccdc2c24..d08ec6bb4 100644 --- a/src/kmap2qmap/kmap2qmap.pro +++ b/src/kmap2qmap/kmap2qmap.pro @@ -1,4 +1,4 @@ -QT = core platformsupport-private +QT = core input_support-private CONFIG += console SOURCES += main.cpp diff --git a/src/kmap2qmap/main.cpp b/src/kmap2qmap/main.cpp index 453d20a0a..9fd7e9ae8 100644 --- a/src/kmap2qmap/main.cpp +++ b/src/kmap2qmap/main.cpp @@ -38,7 +38,7 @@ #include <QStringList> #include <QTextStream> -#include <QtPlatformSupport/private/qevdevkeyboardhandler_p.h> +#include <QtInputSupport/private/qevdevkeyboardhandler_p.h> using namespace std; diff --git a/src/linguist/lconvert/main.cpp b/src/linguist/lconvert/main.cpp index 565154520..4e26adbbb 100644 --- a/src/linguist/lconvert/main.cpp +++ b/src/linguist/lconvert/main.cpp @@ -50,7 +50,7 @@ static int usage(const QStringList &args) QString loaders; QString line(QLatin1String(" %1 - %2\n")); foreach (Translator::FileFormat format, Translator::registeredFileFormats()) - loaders += line.arg(format.extension, -5).arg(format.description); + loaders += line.arg(format.extension, -5).arg(format.description()); std::cout << qPrintable(LC::tr("\nUsage:\n" " lconvert [options] <infile> [<infile>...]\n\n" diff --git a/src/linguist/linguist/mainwindow.cpp b/src/linguist/linguist/mainwindow.cpp index 282e2adea..cd460711b 100644 --- a/src/linguist/linguist/mainwindow.cpp +++ b/src/linguist/linguist/mainwindow.cpp @@ -743,7 +743,7 @@ static QString fileFilters(bool allFirst) QString filter; foreach (const Translator::FileFormat &format, Translator::registeredFileFormats()) { if (format.fileType == Translator::FileFormat::TranslationSource && format.priority >= 0) { - filter.append(pattern.arg(format.description).arg(format.extension)); + filter.append(pattern.arg(format.description(), format.extension)); allExtensions.append(QLatin1String("*.") + format.extension); } } diff --git a/src/linguist/shared/po.cpp b/src/linguist/shared/po.cpp index a6fd895ec..5bbaf97c0 100644 --- a/src/linguist/shared/po.cpp +++ b/src/linguist/shared/po.cpp @@ -883,14 +883,14 @@ int initPO() { Translator::FileFormat format; format.extension = QLatin1String("po"); - format.description = FMT::tr("GNU Gettext localization files"); + format.untranslatedDescription = QT_TRANSLATE_NOOP("FMT", "GNU Gettext localization files"); format.loader = &loadPO; format.saver = &savePO; format.fileType = Translator::FileFormat::TranslationSource; format.priority = 1; Translator::registerFileFormat(format); format.extension = QLatin1String("pot"); - format.description = FMT::tr("GNU Gettext localization template files"); + format.untranslatedDescription = QT_TRANSLATE_NOOP("FMT", "GNU Gettext localization template files"); format.loader = &loadPO; format.saver = &savePOT; format.fileType = Translator::FileFormat::TranslationSource; diff --git a/src/linguist/shared/proitems.cpp b/src/linguist/shared/proitems.cpp index 2afef21a3..37ec0c76b 100644 --- a/src/linguist/shared/proitems.cpp +++ b/src/linguist/shared/proitems.cpp @@ -365,6 +365,11 @@ static QString ProStringList_join(const ProStringList &this_, const QChar *sep, return res; } +QString ProStringList::join(const ProString &sep) const +{ + return ProStringList_join(*this, sep.constData(), sep.size()); +} + QString ProStringList::join(const QString &sep) const { return ProStringList_join(*this, sep.constData(), sep.size()); @@ -391,7 +396,7 @@ void ProStringList::removeAll(const char *str) void ProStringList::removeEach(const ProStringList &value) { - foreach (const ProString &str, value) + for (const ProString &str : value) if (!str.isEmpty()) removeAll(str); } @@ -424,7 +429,7 @@ void ProStringList::removeDuplicates() void ProStringList::insertUnique(const ProStringList &value) { - foreach (const ProString &str, value) + for (const ProString &str : value) if (!str.isEmpty() && !contains(str)) append(str); } @@ -432,7 +437,7 @@ void ProStringList::insertUnique(const ProStringList &value) ProStringList::ProStringList(const QStringList &list) { reserve(list.size()); - foreach (const QString &str, list) + for (const QString &str : list) *this << ProString(str); } @@ -440,8 +445,8 @@ QStringList ProStringList::toQStringList() const { QStringList ret; ret.reserve(size()); - for (int i = 0; i < size(); i++) // foreach causes MSVC2010 ICE - ret << at(i).toQString(); + for (const auto &e : *this) + ret.append(e.toQString()); return ret; } @@ -453,6 +458,14 @@ bool ProStringList::contains(const ProString &str, Qt::CaseSensitivity cs) const return false; } +bool ProStringList::contains(const QStringRef &str, Qt::CaseSensitivity cs) const +{ + for (int i = 0; i < size(); i++) + if (!at(i).toQStringRef().compare(str, cs)) + return true; + return false; +} + bool ProStringList::contains(const char *str, Qt::CaseSensitivity cs) const { for (int i = 0; i < size(); i++) diff --git a/src/linguist/shared/proitems.h b/src/linguist/shared/proitems.h index 0787a1d8f..cd7a9f280 100644 --- a/src/linguist/shared/proitems.h +++ b/src/linguist/shared/proitems.h @@ -100,6 +100,7 @@ public: bool operator!=(const QString &other) const { return !(*this == other); } bool operator!=(QLatin1String other) const { return !(*this == other); } bool operator!=(const char *other) const { return !(*this == other); } + bool operator<(const ProString &other) const { return toQStringRef() < other.toQStringRef(); } bool isNull() const { return m_string.isNull(); } bool isEmpty() const { return !m_length; } int length() const { return m_length; } @@ -130,8 +131,9 @@ public: bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(s, 0, cs) >= 0; } bool contains(const char *s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(QLatin1String(s), 0, cs) >= 0; } bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(c, 0, cs) >= 0; } - int toInt(bool *ok = 0, int base = 10) const { return toQString().toInt(ok, base); } // XXX optimize - short toShort(bool *ok = 0, int base = 10) const { return toQString().toShort(ok, base); } // XXX optimize + int toLongLong(bool *ok = 0, int base = 10) const { return toQStringRef().toLongLong(ok, base); } + int toInt(bool *ok = 0, int base = 10) const { return toQStringRef().toInt(ok, base); } + short toShort(bool *ok = 0, int base = 10) const { return toQStringRef().toShort(ok, base); } uint hash() const { return m_hash; } static uint hash(const QChar *p, int n); @@ -206,9 +208,13 @@ inline QString operator+(const QString &one, const ProString &two) { return ProString(one) + two; } inline QString operator+(const ProString &one, const char *two) - { return one + ProString(two); } // XXX optimize + { QString ret = one.toQStringRef() + QLatin1String(two); ret.detach(); return ret; } inline QString operator+(const char *one, const ProString &two) - { return ProString(one) + two; } // XXX optimize + { QString ret = QLatin1String(one) + two.toQStringRef(); ret.detach(); return ret; } +inline QString operator+(const ProString &one, QChar two) + { return one.toQStringRef() + two; } +inline QString operator+(QChar one, const ProString &two) + { return one + two.toQStringRef(); } inline QString &operator+=(QString &that, const ProString &other) { return that += other.toQStringRef(); } @@ -232,6 +238,7 @@ public: int length() const { return size(); } + QString join(const ProString &sep) const; QString join(const QString &sep) const; QString join(QChar sep) const; @@ -245,6 +252,7 @@ public: void removeDuplicates(); bool contains(const ProString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; + bool contains(const QStringRef &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; bool contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return contains(ProString(str), cs); } bool contains(const char *str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; @@ -364,6 +372,8 @@ class ProFunctionDef { public: ProFunctionDef(ProFile *pro, int offset) : m_pro(pro), m_offset(offset) { m_pro->ref(); } ProFunctionDef(const ProFunctionDef &o) : m_pro(o.m_pro), m_offset(o.m_offset) { m_pro->ref(); } + ProFunctionDef(ProFunctionDef &&other) Q_DECL_NOTHROW + : m_pro(other.m_pro), m_offset(other.m_offset) { other.m_pro = nullptr; } ~ProFunctionDef() { m_pro->deref(); } ProFunctionDef &operator=(const ProFunctionDef &o) { @@ -375,6 +385,18 @@ public: } return *this; } + ProFunctionDef &operator=(ProFunctionDef &&other) Q_DECL_NOTHROW + { + ProFunctionDef moved(std::move(other)); + swap(moved); + return *this; + } + void swap(ProFunctionDef &other) Q_DECL_NOTHROW + { + qSwap(m_pro, other.m_pro); + qSwap(m_offset, other.m_offset); + } + ProFile *pro() const { return m_pro; } const ushort *tokPtr() const { return m_pro->tokPtr() + m_offset; } private: diff --git a/src/linguist/shared/qm.cpp b/src/linguist/shared/qm.cpp index 95708ef4f..cdca3a113 100644 --- a/src/linguist/shared/qm.cpp +++ b/src/linguist/shared/qm.cpp @@ -721,7 +721,7 @@ int initQM() Translator::FileFormat format; format.extension = QLatin1String("qm"); - format.description = FMT::tr("Compiled Qt translations"); + format.untranslatedDescription = QT_TRANSLATE_NOOP("FMT", "Compiled Qt translations"); format.fileType = Translator::FileFormat::TranslationBinary; format.priority = 0; format.loader = &loadQM; diff --git a/src/linguist/shared/qmakebuiltins.cpp b/src/linguist/shared/qmakebuiltins.cpp index e3aff7b9e..19fc6d639 100644 --- a/src/linguist/shared/qmakebuiltins.cpp +++ b/src/linguist/shared/qmakebuiltins.cpp @@ -52,6 +52,8 @@ # include <qthreadpool.h> #endif +#include <algorithm> + #ifdef Q_OS_UNIX #include <time.h> #include <utime.h> @@ -84,9 +86,10 @@ QT_BEGIN_NAMESPACE #define fL1S(s) QString::fromLatin1(s) enum ExpandFunc { - E_INVALID = 0, E_MEMBER, E_FIRST, E_LAST, E_SIZE, E_CAT, E_FROMFILE, E_EVAL, E_LIST, - E_SPRINTF, E_FORMAT_NUMBER, E_JOIN, E_SPLIT, E_BASENAME, E_DIRNAME, E_SECTION, - E_FIND, E_SYSTEM, E_UNIQUE, E_REVERSE, E_QUOTE, E_ESCAPE_EXPAND, + E_INVALID = 0, E_MEMBER, E_STR_MEMBER, E_FIRST, E_TAKE_FIRST, E_LAST, E_TAKE_LAST, + E_SIZE, E_STR_SIZE, E_CAT, E_FROMFILE, E_EVAL, E_LIST, E_SPRINTF, E_FORMAT_NUMBER, + E_NUM_ADD, E_JOIN, E_SPLIT, E_BASENAME, E_DIRNAME, E_SECTION, + E_FIND, E_SYSTEM, E_UNIQUE, E_SORTED, E_REVERSE, E_QUOTE, E_ESCAPE_EXPAND, E_UPPER, E_LOWER, E_TITLE, E_FILES, E_PROMPT, E_RE_ESCAPE, E_VAL_ESCAPE, E_REPLACE, E_SORT_DEPENDS, E_RESOLVE_DEPENDS, E_ENUMERATE_VARS, E_SHADOWED, E_ABSOLUTE_PATH, E_RELATIVE_PATH, E_CLEAN_PATH, @@ -96,7 +99,7 @@ enum ExpandFunc { enum TestFunc { T_INVALID = 0, T_REQUIRES, T_GREATERTHAN, T_LESSTHAN, T_EQUALS, T_EXISTS, T_EXPORT, T_CLEAR, T_UNSET, T_EVAL, T_CONFIG, T_SYSTEM, - T_DEFINED, T_CONTAINS, T_INFILE, + T_DEFINED, T_DISCARD_FROM, T_CONTAINS, T_INFILE, T_COUNT, T_ISEMPTY, T_PARSE_JSON, T_INCLUDE, T_LOAD, T_DEBUG, T_LOG, T_MESSAGE, T_WARNING, T_ERROR, T_IF, T_MKPATH, T_WRITE_FILE, T_TOUCH, T_CACHE }; @@ -108,15 +111,20 @@ void QMakeEvaluator::initFunctionStatics() const ExpandFunc func; } expandInits[] = { { "member", E_MEMBER }, + { "str_member", E_STR_MEMBER }, { "first", E_FIRST }, + { "take_first", E_TAKE_FIRST }, { "last", E_LAST }, + { "take_last", E_TAKE_LAST }, { "size", E_SIZE }, + { "str_size", E_STR_SIZE }, { "cat", E_CAT }, { "fromfile", E_FROMFILE }, { "eval", E_EVAL }, { "list", E_LIST }, { "sprintf", E_SPRINTF }, { "format_number", E_FORMAT_NUMBER }, + { "num_add", E_NUM_ADD }, { "join", E_JOIN }, { "split", E_SPLIT }, { "basename", E_BASENAME }, @@ -125,6 +133,7 @@ void QMakeEvaluator::initFunctionStatics() { "find", E_FIND }, { "system", E_SYSTEM }, { "unique", E_UNIQUE }, + { "sorted", E_SORTED }, { "reverse", E_REVERSE }, { "quote", E_QUOTE }, { "escape_expand", E_ESCAPE_EXPAND }, @@ -149,6 +158,7 @@ void QMakeEvaluator::initFunctionStatics() { "shell_quote", E_SHELL_QUOTE }, { "getenv", E_GETENV }, }; + statics.expands.reserve((int)(sizeof(expandInits)/sizeof(expandInits[0]))); for (unsigned i = 0; i < sizeof(expandInits)/sizeof(expandInits[0]); ++i) statics.expands.insert(ProKey(expandInits[i].name), expandInits[i].func); @@ -170,6 +180,7 @@ void QMakeEvaluator::initFunctionStatics() { "if", T_IF }, { "isActiveConfig", T_CONFIG }, { "system", T_SYSTEM }, + { "discard_from", T_DISCARD_FROM }, { "defined", T_DEFINED }, { "contains", T_CONTAINS }, { "infile", T_INFILE }, @@ -190,16 +201,59 @@ void QMakeEvaluator::initFunctionStatics() { "touch", T_TOUCH }, { "cache", T_CACHE }, }; + statics.functions.reserve((int)(sizeof(testInits)/sizeof(testInits[0]))); for (unsigned i = 0; i < sizeof(testInits)/sizeof(testInits[0]); ++i) statics.functions.insert(ProKey(testInits[i].name), testInits[i].func); } -static bool isTrue(const ProString &_str, QString &tmp) +static bool isTrue(const ProString &str) { - const QString &str = _str.toQString(tmp); return !str.compare(statics.strtrue, Qt::CaseInsensitive) || str.toInt(); } +bool +QMakeEvaluator::getMemberArgs(const ProKey &func, int srclen, const ProStringList &args, + int *start, int *end) +{ + *start = 0, *end = 0; + if (args.count() >= 2) { + bool ok = true; + const ProString &start_str = args.at(1); + *start = start_str.toInt(&ok); + if (!ok) { + if (args.count() == 2) { + int dotdot = start_str.indexOf(statics.strDotDot); + if (dotdot != -1) { + *start = start_str.left(dotdot).toInt(&ok); + if (ok) + *end = start_str.mid(dotdot+2).toInt(&ok); + } + } + if (!ok) { + evalError(fL1S("%1() argument 2 (start) '%2' invalid.") + .arg(func.toQString(m_tmp1), start_str.toQString(m_tmp2))); + return false; + } + } else { + *end = *start; + if (args.count() == 3) + *end = args.at(2).toInt(&ok); + if (!ok) { + evalError(fL1S("%1() argument 3 (end) '%2' invalid.") + .arg(func.toQString(m_tmp1), args.at(2).toQString(m_tmp2))); + return false; + } + } + } + if (*start < 0) + *start += srclen; + if (*end < 0) + *end += srclen; + if (*start < 0 || *start >= srclen || *end < 0 || *end >= srclen) + return false; + return true; +} + #if defined(Q_OS_WIN) && defined(PROEVALUATOR_FULL) static QString windowsErrorCode() { @@ -270,7 +324,7 @@ QMakeEvaluator::quoteValue(const ProString &val) break; case 32: quote = true; - // fallthrough + Q_FALLTHROUGH(); default: ret += c; break; @@ -297,19 +351,26 @@ static void insertJsonKeyValue(const QString &key, const QStringList &values, Pr static void addJsonArray(const QJsonArray &array, const QString &keyPrefix, ProValueMap *map) { QStringList keys; - for (int i = 0; i < array.count(); ++i) { - keys.append(QString::number(i)); - addJsonValue(array.at(i), keyPrefix + QString::number(i), map); + const int size = array.count(); + keys.reserve(size); + for (int i = 0; i < size; ++i) { + const QString number = QString::number(i); + keys.append(number); + addJsonValue(array.at(i), keyPrefix + number, map); } insertJsonKeyValue(keyPrefix + QLatin1String("_KEYS_"), keys, map); } static void addJsonObject(const QJsonObject &object, const QString &keyPrefix, ProValueMap *map) { - foreach (const QString &key, object.keys()) - addJsonValue(object.value(key), keyPrefix + key, map); - - insertJsonKeyValue(keyPrefix + QLatin1String("_KEYS_"), object.keys(), map); + QStringList keys; + keys.reserve(object.size()); + for (auto it = object.begin(), end = object.end(); it != end; ++it) { + const QString key = it.key(); + keys.append(key); + addJsonValue(it.value(), keyPrefix + key, map); + } + insertJsonKeyValue(keyPrefix + QLatin1String("_KEYS_"), keys, map); } static void addJsonValue(const QJsonValue &value, const QString &keyPrefix, ProValueMap *map) @@ -335,11 +396,16 @@ static void addJsonValue(const QJsonValue &value, const QString &keyPrefix, ProV } } -static QMakeEvaluator::VisitReturn parseJsonInto(const QByteArray &json, const QString &into, ProValueMap *value) +QMakeEvaluator::VisitReturn QMakeEvaluator::parseJsonInto(const QByteArray &json, const QString &into, ProValueMap *value) { - QJsonDocument document = QJsonDocument::fromJson(json); - if (document.isNull()) + QJsonParseError error; + QJsonDocument document = QJsonDocument::fromJson(json, &error); + if (document.isNull()) { + if (error.error != QJsonParseError::NoError) + evalError(fL1S("Error parsing json at offset %1: %2") + .arg(error.offset).arg(error.errorString())); return QMakeEvaluator::ReturnFalse; + } QString currentKey = into + QLatin1Char('.'); @@ -387,12 +453,13 @@ void QMakeEvaluator::runProcess(QProcess *proc, const QString &command) const } #endif -QByteArray QMakeEvaluator::getCommandOutput(const QString &args) const +QByteArray QMakeEvaluator::getCommandOutput(const QString &args, int *exitCode) const { QByteArray out; #ifndef QT_BOOTSTRAPPED QProcess proc; runProcess(&proc, args); + *exitCode = (proc.exitStatus() == QProcess::NormalExit) ? proc.exitCode() : -1; QByteArray errout = proc.readAllStandardError(); # ifdef PROEVALUATOR_FULL // FIXME: Qt really should have the option to set forwarding per channel @@ -422,7 +489,12 @@ QByteArray QMakeEvaluator::getCommandOutput(const QString &args) const break; out += QByteArray(buff, read_in); } - QT_PCLOSE(proc); + int ec = QT_PCLOSE(proc); +# ifdef Q_OS_WIN + *exitCode = ec >= 0 ? ec : -1; +# else + *exitCode = WIFEXITED(ec) ? WEXITSTATUS(ec) : -1; +# endif } # ifdef Q_OS_WIN out.replace("\r\n", "\n"); @@ -437,16 +509,16 @@ void QMakeEvaluator::populateDeps( QHash<ProKey, QSet<ProKey> > &dependencies, ProValueMap &dependees, QMultiMap<int, ProString> &rootSet) const { - foreach (const ProString &item, deps) + for (const ProString &item : deps) if (!dependencies.contains(item.toKey())) { QSet<ProKey> &dset = dependencies[item.toKey()]; // Always create entry ProStringList depends; - foreach (const ProString &suffix, suffixes) + for (const ProString &suffix : suffixes) depends += values(ProKey(prefix + item + suffix)); if (depends.isEmpty()) { rootSet.insert(first(ProKey(prefix + item + priosfx)).toInt(), item); } else { - foreach (const ProString &dep, depends) { + for (const ProString &dep : qAsConst(depends)) { dset.insert(dep.toKey()); dependees[dep.toKey()] << item; } @@ -478,9 +550,9 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( } else { var = args[0]; sep = args.at(1).toQString(); - beg = args.at(2).toQString(m_tmp2).toInt(); + beg = args.at(2).toInt(); if (args.count() == 4) - end = args.at(3).toQString(m_tmp2).toInt(); + end = args.at(3).toInt(); } } else { if (args.count() != 1) { @@ -496,14 +568,15 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( } } if (!var.isEmpty()) { + const auto strings = values(map(var)); if (regexp) { QRegExp sepRx(sep); - foreach (const ProString &str, values(map(var))) { + for (const ProString &str : strings) { const QString &rstr = str.toQString(m_tmp1).section(sepRx, beg, end); ret << (rstr.isSharedWith(m_tmp1) ? str : ProString(rstr).setSource(str)); } } else { - foreach (const ProString &str, values(map(var))) { + for (const ProString &str : strings) { const QString &rstr = str.toQString(m_tmp1).section(sep, beg, end); ret << (rstr.isSharedWith(m_tmp1) ? str : ProString(rstr).setSource(str)); } @@ -532,38 +605,38 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( bool leftalign = false; enum { DefaultSign, PadSign, AlwaysSign } sign = DefaultSign; if (args.count() >= 2) { - foreach (const ProString &opt, split_value_list(args.at(1).toQString(m_tmp2))) { - opt.toQString(m_tmp3); - if (m_tmp3.startsWith(QLatin1String("ibase="))) { - ibase = m_tmp3.mid(6).toInt(); - } else if (m_tmp3.startsWith(QLatin1String("obase="))) { - obase = m_tmp3.mid(6).toInt(); - } else if (m_tmp3.startsWith(QLatin1String("width="))) { - width = m_tmp3.mid(6).toInt(); - } else if (m_tmp3 == QLatin1String("zeropad")) { + const auto opts = split_value_list(args.at(1).toQStringRef()); + for (const ProString &opt : opts) { + if (opt.startsWith(QLatin1String("ibase="))) { + ibase = opt.mid(6).toInt(); + } else if (opt.startsWith(QLatin1String("obase="))) { + obase = opt.mid(6).toInt(); + } else if (opt.startsWith(QLatin1String("width="))) { + width = opt.mid(6).toInt(); + } else if (opt == QLatin1String("zeropad")) { zeropad = true; - } else if (m_tmp3 == QLatin1String("padsign")) { + } else if (opt == QLatin1String("padsign")) { sign = PadSign; - } else if (m_tmp3 == QLatin1String("alwayssign")) { + } else if (opt == QLatin1String("alwayssign")) { sign = AlwaysSign; - } else if (m_tmp3 == QLatin1String("leftalign")) { + } else if (opt == QLatin1String("leftalign")) { leftalign = true; } else { - evalError(fL1S("format_number(): invalid format option %1.").arg(m_tmp3)); + evalError(fL1S("format_number(): invalid format option %1.") + .arg(opt.toQString(m_tmp3))); goto formfail; } } } - args.at(0).toQString(m_tmp3); - if (m_tmp3.contains(QLatin1Char('.'))) { + if (args.at(0).contains(QLatin1Char('.'))) { evalError(fL1S("format_number(): floats are currently not supported.")); break; } bool ok; - qlonglong num = m_tmp3.toLongLong(&ok, ibase); + qlonglong num = args.at(0).toLongLong(&ok, ibase); if (!ok) { evalError(fL1S("format_number(): malformed number %2 for base %1.") - .arg(ibase).arg(m_tmp3)); + .arg(ibase).arg(args.at(0).toQString(m_tmp3))); break; } QString outstr; @@ -591,14 +664,36 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( } formfail: break; + case E_NUM_ADD: + if (args.count() < 1 || args.at(0).isEmpty()) { + evalError(fL1S("num_add(num, ...) requires at least one argument.")); + } else { + qlonglong sum = 0; + for (const ProString &arg : qAsConst(args)) { + if (arg.contains(QLatin1Char('.'))) { + evalError(fL1S("num_add(): floats are currently not supported.")); + goto nafail; + } + bool ok; + qlonglong num = arg.toLongLong(&ok); + if (!ok) { + evalError(fL1S("num_add(): malformed number %1.") + .arg(arg.toQString(m_tmp3))); + goto nafail; + } + sum += num; + } + ret += ProString(QString::number(sum)); + } + nafail: + break; case E_JOIN: { if (args.count() < 1 || args.count() > 4) { evalError(fL1S("join(var, glue, before, after) requires one to four arguments.")); } else { - QString glue; - ProString before, after; + ProString glue, before, after; if (args.count() >= 2) - glue = args.at(1).toQString(m_tmp1); + glue = args.at(1); if (args.count() >= 3) before = args[2]; if (args.count() == 4) @@ -606,7 +701,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( const ProStringList &var = values(map(args.at(0))); if (!var.isEmpty()) { const ProFile *src = currentProFile(); - foreach (const ProString &v, var) + for (const ProString &v : var) if (const ProFile *s = v.sourceFile()) { src = s; break; @@ -621,56 +716,49 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( evalError(fL1S("split(var, sep) requires one or two arguments.")); } else { const QString &sep = (args.count() == 2) ? args.at(1).toQString(m_tmp1) : statics.field_sep; - foreach (const ProString &var, values(map(args.at(0)))) - foreach (const QString &splt, var.toQString(m_tmp2).split(sep)) + const auto vars = values(map(args.at(0))); + for (const ProString &var : vars) { + const auto splits = var.toQString(m_tmp2).split(sep); + for (const QString &splt : splits) ret << (splt.isSharedWith(m_tmp2) ? var : ProString(splt).setSource(var)); + } } break; case E_MEMBER: if (args.count() < 1 || args.count() > 3) { evalError(fL1S("member(var, start, end) requires one to three arguments.")); } else { - bool ok = true; - const ProStringList &var = values(map(args.at(0))); - int start = 0, end = 0; - if (args.count() >= 2) { - const QString &start_str = args.at(1).toQString(m_tmp1); - start = start_str.toInt(&ok); - if (!ok) { - if (args.count() == 2) { - int dotdot = start_str.indexOf(statics.strDotDot); - if (dotdot != -1) { - start = start_str.left(dotdot).toInt(&ok); - if (ok) - end = start_str.mid(dotdot+2).toInt(&ok); - } - } - if (!ok) - evalError(fL1S("member() argument 2 (start) '%2' invalid.") - .arg(start_str)); + const ProStringList &src = values(map(args.at(0))); + int start, end; + if (getMemberArgs(func, src.size(), args, &start, &end)) { + ret.reserve(qAbs(end - start) + 1); + if (start < end) { + for (int i = start; i <= end && src.size() >= i; i++) + ret += src.at(i); } else { - end = start; - if (args.count() == 3) - end = args.at(2).toQString(m_tmp1).toInt(&ok); - if (!ok) - evalError(fL1S("member() argument 3 (end) '%2' invalid.") - .arg(args.at(2).toQString(m_tmp1))); + for (int i = start; i >= end && src.size() >= i && i >= 0; i--) + ret += src.at(i); } } - if (ok) { - if (start < 0) - start += var.count(); - if (end < 0) - end += var.count(); - if (start < 0 || start >= var.count() || end < 0 || end >= var.count()) { - //nothing - } else if (start < end) { - for (int i = start; i <= end && var.count() >= i; i++) - ret.append(var[i]); + } + break; + case E_STR_MEMBER: + if (args.count() < 1 || args.count() > 3) { + evalError(fL1S("str_member(str, start, end) requires one to three arguments.")); + } else { + const ProString &src = args.at(0); + int start, end; + if (getMemberArgs(func, src.size(), args, &start, &end)) { + QString res; + res.reserve(qAbs(end - start) + 1); + if (start < end) { + for (int i = start; i <= end && src.size() >= i; i++) + res += src.at(i); } else { - for (int i = start; i >= end && var.count() >= i && i >= 0; i--) - ret += var[i]; + for (int i = start; i >= end && src.size() >= i && i >= 0; i--) + res += src.at(i); } + ret += ProString(res); } } break; @@ -688,12 +776,32 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( } } break; + case E_TAKE_FIRST: + case E_TAKE_LAST: + if (args.count() != 1) { + evalError(fL1S("%1(var) requires one argument.").arg(func.toQString(m_tmp1))); + } else { + ProStringList &var = valuesRef(map(args.at(0))); + if (!var.isEmpty()) { + if (func_t == E_TAKE_FIRST) + ret.append(var.takeFirst()); + else + ret.append(var.takeLast()); + } + } + break; case E_SIZE: if (args.count() != 1) evalError(fL1S("size(var) requires one argument.")); else ret.append(ProString(QString::number(values(map(args.at(0))).size()))); break; + case E_STR_SIZE: + if (args.count() != 1) + evalError(fL1S("str_size(str) requires one argument.")); + else + ret.append(ProString(QString::number(args.at(0).size()))); + break; case E_CAT: if (args.count() < 1 || args.count() > 2) { evalError(fL1S("cat(file, singleline=true) requires one or two arguments.")); @@ -704,12 +812,11 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( bool lines = false; bool singleLine = true; if (args.count() > 1) { - args.at(1).toQString(m_tmp2); - if (!m_tmp2.compare(QLatin1String("false"), Qt::CaseInsensitive)) + if (!args.at(1).compare(QLatin1String("false"), Qt::CaseInsensitive)) singleLine = false; - else if (!m_tmp2.compare(QLatin1String("blob"), Qt::CaseInsensitive)) + else if (!args.at(1).compare(QLatin1String("blob"), Qt::CaseInsensitive)) blob = true; - else if (!m_tmp2.compare(QLatin1String("lines"), Qt::CaseInsensitive)) + else if (!args.at(1).compare(QLatin1String("lines"), Qt::CaseInsensitive)) lines = true; } @@ -723,7 +830,8 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( if (lines) { ret += ProString(stream.readLine()); } else { - ret += split_value_list(stream.readLine().trimmed()); + const QString &line = stream.readLine(); + ret += split_value_list(QStringRef(&line).trimmed()); if (!singleLine) ret += ProString("\n"); } @@ -754,8 +862,8 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( tmp.sprintf(".QMAKE_INTERNAL_TMP_variableName_%d", m_listCount++); ret = ProStringList(ProString(tmp)); ProStringList lst; - foreach (const ProString &arg, args) - lst += split_value_list(arg.toQString(m_tmp1), arg.sourceFile()); // Relies on deep copy + for (const ProString &arg : args) + lst += split_value_list(arg.toQStringRef(), arg.sourceFile()); // Relies on deep copy m_valuemapStack.top()[ret.at(0).toKey()] = lst; break; } case E_FIND: @@ -764,7 +872,8 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( } else { QRegExp regx(args.at(1).toQString()); int t = 0; - foreach (const ProString &val, values(map(args.at(0)))) { + const auto vals = values(map(args.at(0))); + for (const ProString &val : vals) { if (regx.indexIn(val.toQString(m_tmp[t])) != -1) ret += val; t ^= 1; @@ -773,22 +882,26 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( break; case E_SYSTEM: if (!m_skipLevel) { - if (args.count() < 1 || args.count() > 2) { - evalError(fL1S("system(execute) requires one or two arguments.")); + if (args.count() < 1 || args.count() > 3) { + evalError(fL1S("system(command, [mode], [stsvar]) requires one to three arguments.")); } else { bool blob = false; bool lines = false; bool singleLine = true; if (args.count() > 1) { - args.at(1).toQString(m_tmp2); - if (!m_tmp2.compare(QLatin1String("false"), Qt::CaseInsensitive)) + if (!args.at(1).compare(QLatin1String("false"), Qt::CaseInsensitive)) singleLine = false; - else if (!m_tmp2.compare(QLatin1String("blob"), Qt::CaseInsensitive)) + else if (!args.at(1).compare(QLatin1String("blob"), Qt::CaseInsensitive)) blob = true; - else if (!m_tmp2.compare(QLatin1String("lines"), Qt::CaseInsensitive)) + else if (!args.at(1).compare(QLatin1String("lines"), Qt::CaseInsensitive)) lines = true; } - QByteArray bytes = getCommandOutput(args.at(0).toQString(m_tmp2)); + int exitCode; + QByteArray bytes = getCommandOutput(args.at(0).toQString(m_tmp2), &exitCode); + if (args.count() > 2 && !args.at(2).isEmpty()) { + m_valuemapStack.top()[args.at(2).toKey()] = + ProStringList(ProString(QString::number(exitCode))); + } if (lines) { QTextStream stream(bytes); while (!stream.atEnd()) @@ -801,7 +914,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( output.replace(QLatin1Char('\t'), QLatin1Char(' ')); if (singleLine) output.replace(QLatin1Char('\n'), QLatin1Char(' ')); - ret += split_value_list(output); + ret += split_value_list(QStringRef(&output)); } } } @@ -815,6 +928,14 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( ret.removeDuplicates(); } break; + case E_SORTED: + if (args.count() != 1) { + evalError(fL1S("sorted(var) requires one argument.")); + } else { + ret = values(map(args.at(0))); + std::sort(ret.begin(), ret.end()); + } + break; case E_REVERSE: if (args.count() != 1) { evalError(fL1S("reverse(var) requires one argument.")); @@ -873,7 +994,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( } else { const ProStringList &vals = values(args.at(0).toKey()); ret.reserve(vals.size()); - foreach (const ProString &str, vals) + for (const ProString &str : vals) ret += ProString(quoteValue(str)); } break; @@ -898,7 +1019,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( } else { bool recursive = false; if (args.count() == 2) - recursive = isTrue(args.at(1), m_tmp2); + recursive = isTrue(args.at(1)); QStringList dirs; QString r = m_option->expandEnvVars(args.at(0).toQString(m_tmp1)) .replace(QLatin1Char('\\'), QLatin1Char('/')); @@ -950,7 +1071,8 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( QFile qfile; if (qfile.open(stdin, QIODevice::ReadOnly)) { QTextStream t(&qfile); - ret = split_value_list(t.readLine()); + const QString &line = t.readLine(); + ret = split_value_list(QStringRef(&line)); } } break; } @@ -961,7 +1083,8 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( } else { const QRegExp before(args.at(1).toQString()); const QString &after(args.at(2).toQString(m_tmp2)); - foreach (const ProString &val, values(map(args.at(0)))) { + const auto vals = values(map(args.at(0))); + for (const ProString &val : vals) { QString rstr = val.toQString(m_tmp1); QString copy = rstr; // Force a detach on modify rstr.replace(before, after); @@ -983,7 +1106,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( ProString priosfx = args.count() < 4 ? ProString(".priority") : args.at(3); populateDeps(orgList, prefix, args.count() < 3 ? ProStringList(ProString(".depends")) - : split_value_list(args.at(2).toQString(m_tmp2)), + : split_value_list(args.at(2).toQStringRef()), priosfx, dependencies, dependees, rootSet); while (!rootSet.isEmpty()) { QMultiMap<int, ProString>::iterator it = rootSet.begin(); @@ -991,7 +1114,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( rootSet.erase(it); if ((func_t == E_RESOLVE_DEPENDS) || orgList.contains(item)) ret.prepend(item); - foreach (const ProString &dep, dependees[item.toKey()]) { + for (const ProString &dep : qAsConst(dependees[item.toKey()])) { QSet<ProKey> &dset = dependencies[dep.toKey()]; dset.remove(item.toKey()); if (dset.isEmpty()) @@ -1002,11 +1125,11 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( break; case E_ENUMERATE_VARS: { QSet<ProString> keys; - foreach (const ProValueMap &vmap, m_valuemapStack) + for (const ProValueMap &vmap : qAsConst(m_valuemapStack)) for (ProValueMap::ConstIterator it = vmap.constBegin(); it != vmap.constEnd(); ++it) keys.insert(it.key()); ret.reserve(keys.size()); - foreach (const ProString &key, keys) + for (const ProString &key : qAsConst(keys)) ret << key; break; } case E_SHADOWED: @@ -1174,6 +1297,38 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( } return ReturnTrue; } + case T_DISCARD_FROM: { + if (args.count() != 1 || args.at(0).isEmpty()) { + evalError(fL1S("discard_from(file) requires one argument.")); + return ReturnFalse; + } + if (m_valuemapStack.count() != 1) { + evalError(fL1S("discard_from() cannot be called from functions.")); + return ReturnFalse; + } + QString fn = resolvePath(args.at(0).toQString(m_tmp1)); + ProFile *pro = m_parser->parsedProFile(fn, QMakeParser::ParseOnlyCached); + if (!pro) + return ReturnFalse; + ProValueMap &vmap = m_valuemapStack.first(); + for (auto vit = vmap.begin(); vit != vmap.end(); ) { + if (!vit->isEmpty()) { + auto isFrom = [pro](const ProString &s) { + return s.sourceFile() == pro; + }; + vit->erase(std::remove_if(vit->begin(), vit->end(), isFrom), vit->end()); + if (vit->isEmpty()) { + // When an initially non-empty variable becomes entirely empty, + // undefine it altogether. + vit = vmap.erase(vit); + continue; + } + } + ++vit; + } + pro->deref(); + return ReturnTrue; + } case T_INFILE: if (args.count() < 2 || args.count() > 3) { evalError(fL1S("infile(file, var, [values]) requires two or three arguments.")); @@ -1194,7 +1349,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( regx.setPattern(copy); } int t = 0; - foreach (const ProString &s, vars.value(map(args.at(1)))) { + const auto strings = vars.value(map(args.at(1))); + for (const ProString &s : strings) { if ((!regx.isEmpty() && regx.exactMatch(s.toQString(m_tmp[t]))) || s == qry) return ReturnTrue; t ^= 1; @@ -1209,7 +1365,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( return ReturnFalse; // Another qmake breakage case T_EVAL: { VisitReturn ret = ReturnFalse; - ProFile *pro = m_parser->parsedProBlock(args.join(statics.field_sep), + QString contents = args.join(statics.field_sep); + ProFile *pro = m_parser->parsedProBlock(QStringRef(&contents), m_current.pro->fileName(), m_current.line); if (m_cumulative || pro->isOk()) { m_locationStack.push(m_current); @@ -1225,7 +1382,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( evalError(fL1S("if(condition) requires one argument.")); return ReturnFalse; } - return evaluateConditional(args.at(0).toQString(), + return evaluateConditional(args.at(0).toQStringRef(), m_current.pro->fileName(), m_current.line); } case T_CONFIG: { @@ -1234,7 +1391,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( return ReturnFalse; } if (args.count() == 1) - return returnBool(isActiveConfig(args.at(0).toQString(m_tmp2))); + return returnBool(isActiveConfig(args.at(0).toQStringRef())); const QStringList &mutuals = args.at(1).toQString(m_tmp2).split(QLatin1Char('|')); const ProStringList &configs = values(statics.strCONFIG); @@ -1289,7 +1446,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( return ReturnFalse; } int cnt = values(map(args.at(0))).count(); - int val = args.at(1).toQString(m_tmp1).toInt(); + int val = args.at(1).toInt(); if (args.count() == 3) { const ProString &comp = args.at(2); if (comp == QLatin1String(">") || comp == QLatin1String("greaterThan")) { @@ -1317,8 +1474,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( .arg(function.toQString(m_tmp1))); return ReturnFalse; } - const QString &rhs(args.at(1).toQString(m_tmp1)), - &lhs(values(map(args.at(0))).join(statics.field_sep)); + const ProString &rhs = args.at(1); + const QString &lhs = values(map(args.at(0))).join(statics.field_sep); bool ok; int rhs_int = rhs.toInt(&ok); if (ok) { // do integer compare @@ -1330,8 +1487,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( } } if (func_t == T_GREATERTHAN) - return returnBool(lhs > rhs); - return returnBool(lhs < rhs); + return returnBool(lhs > rhs.toQStringRef()); + return returnBool(lhs < rhs.toQStringRef()); } case T_EQUALS: if (args.count() != 2) { @@ -1399,8 +1556,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( if (m_cumulative) flags = LoadSilent; if (args.count() >= 2) { - parseInto = args.at(1).toQString(m_tmp2); - if (args.count() >= 3 && isTrue(args.at(2), m_tmp3)) + if (!args.at(1).isEmpty()) + parseInto = args.at(1) + QLatin1Char('.'); + if (args.count() >= 3 && isTrue(args.at(2))) flags = LoadSilent; } QString fn = resolvePath(m_option->expandEnvVars(args.at(0).toQString(m_tmp1))); @@ -1416,17 +1574,15 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( it = m_valuemapStack.top().constBegin(), end = m_valuemapStack.top().constEnd(); it != end; ++it) { - const QString &ky = it.key().toQString(m_tmp1); - if (!(ky.startsWith(parseInto) && - (ky.length() == parseInto.length() - || ky.at(parseInto.length()) == QLatin1Char('.')))) + const ProString &ky = it.key(); + if (!ky.startsWith(parseInto)) newMap[it.key()] = it.value(); } for (ProValueMap::ConstIterator it = symbols.constBegin(); it != symbols.constEnd(); ++it) { const QString &ky = it.key().toQString(m_tmp1); if (!ky.startsWith(QLatin1Char('.'))) - newMap.insert(ProKey(parseInto + QLatin1Char('.') + ky), it.value()); + newMap.insert(ProKey(parseInto + ky), it.value()); } m_valuemapStack.top() = newMap; } @@ -1438,7 +1594,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( case T_LOAD: { bool ignore_error = false; if (args.count() == 2) { - ignore_error = isTrue(args.at(1), m_tmp2); + ignore_error = isTrue(args.at(1)); } else if (args.count() != 1) { evalError(fL1S("load(feature) requires one or two arguments.")); return ReturnFalse; @@ -1478,7 +1634,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( #ifdef PROEVALUATOR_FULL fputs(msg.toLatin1().constData(), stderr); #endif - } else { + } else if (!msg.isEmpty() || func_t != T_ERROR) { m_handler->fileMessage( (func_t == T_ERROR ? QMakeHandler::ErrorMessage : func_t == T_WARNING ? QMakeHandler::WarningMessage : @@ -1572,7 +1728,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( if (!vals.isEmpty()) contents = vals.join(QLatin1Char('\n')) + QLatin1Char('\n'); if (args.count() >= 3) { - foreach (const ProString &opt, split_value_list(args.at(2).toQString(m_tmp2))) { + const auto opts = split_value_list(args.at(2).toQStringRef()); + for (const ProString &opt : opts) { opt.toQString(m_tmp3); if (m_tmp3 == QLatin1String("append")) { mode = QIODevice::Append; @@ -1644,7 +1801,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( enum { CacheSet, CacheAdd, CacheSub } mode = CacheSet; ProKey srcvar; if (args.count() >= 2) { - foreach (const ProString &opt, split_value_list(args.at(1).toQString(m_tmp2))) { + const auto opts = split_value_list(args.at(1).toQStringRef()); + for (const ProString &opt : opts) { opt.toQString(m_tmp3); if (m_tmp3 == QLatin1String("transient")) { persist = false; @@ -1762,7 +1920,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( varstr += QLatin1Char(' '); varstr += quoteValue(diffval.at(0)); } else if (!diffval.isEmpty()) { - foreach (const ProString &vval, diffval) { + for (const ProString &vval : diffval) { varstr += QLatin1String(" \\\n "); varstr += quoteValue(vval); } diff --git a/src/linguist/shared/qmakeevaluator.cpp b/src/linguist/shared/qmakeevaluator.cpp index 7d09ef9b3..7560a4b17 100644 --- a/src/linguist/shared/qmakeevaluator.cpp +++ b/src/linguist/shared/qmakeevaluator.cpp @@ -186,6 +186,7 @@ void QMakeEvaluator::initStatics() { "IN_PWD", "PWD" }, { "DEPLOYMENT", "INSTALLS" } }; + statics.varMap.reserve((int)(sizeof(mapInits)/sizeof(mapInits[0]))); for (unsigned i = 0; i < sizeof(mapInits)/sizeof(mapInits[0]); ++i) statics.varMap.insert(ProKey(mapInits[i].oldname), ProKey(mapInits[i].newname)); } @@ -269,7 +270,7 @@ void QMakeEvaluator::skipHashStr(const ushort *&tokPtr) // FIXME: this should not build new strings for direct sections. // Note that the E_SPRINTF and E_LIST implementations rely on the deep copy. -ProStringList QMakeEvaluator::split_value_list(const QString &vals, const ProFile *source) +ProStringList QMakeEvaluator::split_value_list(const QStringRef &vals, const ProFile *source) { QString build; ProStringList ret; @@ -317,7 +318,7 @@ ProStringList QMakeEvaluator::split_value_list(const QString &vals, const ProFil --x; } } - // fallthrough + Q_FALLTHROUGH(); default: hadWord = true; break; @@ -628,7 +629,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( evalError(fL1S("Conditional must expand to exactly one word.")); okey = false; } else { - okey = isActiveConfig(curr.at(0).toQString(m_tmp2), true); + okey = isActiveConfig(curr.at(0).toQStringRef(), true); traceMsg("condition %s is %s", dbgStr(curr.at(0)), dbgBool(okey)); okey ^= invert; } @@ -763,12 +764,14 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop( if (ok) { int end = itl.mid(dotdot+2).toInt(&ok); if (ok) { - if (m_cumulative && qAbs(end - start) > 100) { + const int absDiff = qAbs(end - start); + if (m_cumulative && absDiff > 100) { // Such a loop is unlikely to contribute something useful to the // file collection, and may cause considerable delay. traceMsg("skipping excessive loop in cumulative mode"); return ReturnFalse; } + list.reserve(absDiff + 1); if (start < end) { for (int i = start; i <= end; i++) list << ProString(QString::number(i)); @@ -987,7 +990,8 @@ static ProString msvcArchitecture(const QString &vcInstallDir, const QString &pa QString vcBinDir = vcInstallDir; if (vcBinDir.endsWith(QLatin1Char('\\'))) vcBinDir.chop(1); - foreach (const QString &dir, pathVar.split(QLatin1Char(';'))) { + const auto dirs = pathVar.split(QLatin1Char(';')); + for (const QString &dir : dirs) { if (!dir.startsWith(vcBinDir, Qt::CaseInsensitive)) continue; const ProString arch = msvcBinDirToQMakeArch(dir.mid(vcBinDir.length() + 1)); @@ -1009,6 +1013,8 @@ void QMakeEvaluator::loadDefaults() vars[ProKey("QMAKE_QMAKE")] << ProString(m_option->qmake_abslocation); if (!m_option->qmake_args.isEmpty()) vars[ProKey("QMAKE_ARGS")] = ProStringList(m_option->qmake_args); + if (!m_option->qtconf.isEmpty()) + vars[ProKey("QMAKE_QTCONF")] = ProString(m_option->qtconf); vars[ProKey("QMAKE_HOST.cpu_count")] = ProString(QString::number(idealThreadCount())); #if defined(Q_OS_WIN32) vars[ProKey("QMAKE_HOST.os")] << ProString("Windows"); @@ -1229,7 +1235,7 @@ bool QMakeEvaluator::loadSpec() qmakespec = m_hostBuild ? QLatin1String("default-host") : QLatin1String("default"); #endif if (IoUtils::isRelativePath(qmakespec)) { - foreach (const QString &root, m_mkspecPaths) { + for (const QString &root : qAsConst(m_mkspecPaths)) { QString mkspec = root + QLatin1Char('/') + qmakespec; if (IoUtils::exists(mkspec)) { qmakespec = mkspec; @@ -1285,7 +1291,7 @@ void QMakeEvaluator::setupProject() void QMakeEvaluator::evaluateCommand(const QString &cmds, const QString &where) { if (!cmds.isEmpty()) { - ProFile *pro = m_parser->parsedProBlock(cmds, where, -1); + ProFile *pro = m_parser->parsedProBlock(QStringRef(&cmds), where, -1); if (pro->isOk()) { m_locationStack.push(m_current); visitProBlock(pro, pro->tokPtr()); @@ -1459,10 +1465,11 @@ void QMakeEvaluator::updateMkspecPaths() QStringList ret; const QString concat = QLatin1String("/mkspecs"); - foreach (const QString &it, m_option->getPathListEnv(QLatin1String("QMAKEPATH"))) + const auto paths = m_option->getPathListEnv(QLatin1String("QMAKEPATH")); + for (const QString &it : paths) ret << it + concat; - foreach (const QString &it, m_qmakepath) + for (const QString &it : qAsConst(m_qmakepath)) ret << it + concat; if (!m_buildRoot.isEmpty()) @@ -1484,11 +1491,8 @@ void QMakeEvaluator::updateFeaturePaths() QStringList feature_roots; - foreach (const QString &f, m_option->getPathListEnv(QLatin1String("QMAKEFEATURES"))) - feature_roots += f; - + feature_roots += m_option->getPathListEnv(QLatin1String("QMAKEFEATURES")); feature_roots += m_qmakefeatures; - feature_roots += m_option->splitPathList( m_option->propertyValue(ProKey("QMAKEFEATURES")).toQString(m_mtmp)); @@ -1502,10 +1506,11 @@ void QMakeEvaluator::updateFeaturePaths() feature_bases << m_sourceRoot; } - foreach (const QString &item, m_option->getPathListEnv(QLatin1String("QMAKEPATH"))) + const auto items = m_option->getPathListEnv(QLatin1String("QMAKEPATH")); + for (const QString &item : items) feature_bases << (item + mkspecs_concat); - foreach (const QString &item, m_qmakepath) + for (const QString &item : qAsConst(m_qmakepath)) feature_bases << (item + mkspecs_concat); if (!m_qmakespec.isEmpty()) { @@ -1527,8 +1532,9 @@ void QMakeEvaluator::updateFeaturePaths() feature_bases << (m_option->propertyValue(ProKey("QT_HOST_DATA/get")) + mkspecs_concat); feature_bases << (m_option->propertyValue(ProKey("QT_HOST_DATA/src")) + mkspecs_concat); - foreach (const QString &fb, feature_bases) { - foreach (const ProString &sfx, values(ProKey("QMAKE_PLATFORM"))) + for (const QString &fb : qAsConst(feature_bases)) { + const auto sfxs = values(ProKey("QMAKE_PLATFORM")); + for (const ProString &sfx : sfxs) feature_roots << (fb + features_concat + sfx + QLatin1Char('/')); feature_roots << (fb + features_concat); } @@ -1540,7 +1546,7 @@ void QMakeEvaluator::updateFeaturePaths() feature_roots.removeDuplicates(); QStringList ret; - foreach (const QString &root, feature_roots) + for (const QString &root : qAsConst(feature_roots)) if (IoUtils::exists(root)) ret << root; m_featureRoots = new QMakeFeatureRoots(ret); @@ -1579,7 +1585,7 @@ QString QMakeEvaluator::currentDirectory() const return QString(); } -bool QMakeEvaluator::isActiveConfig(const QString &config, bool regex) +bool QMakeEvaluator::isActiveConfig(const QStringRef &config, bool regex) { // magic types for easy flipping if (config == statics.strtrue) @@ -1591,7 +1597,7 @@ bool QMakeEvaluator::isActiveConfig(const QString &config, bool regex) return m_hostBuild; if (regex && (config.contains(QLatin1Char('*')) || config.contains(QLatin1Char('?')))) { - QString cfg = config; + QString cfg = config.toString(); cfg.detach(); // Keep m_tmp out of QRegExp's cache QRegExp re(cfg, Qt::CaseSensitive, QRegExp::Wildcard); @@ -1601,7 +1607,8 @@ bool QMakeEvaluator::isActiveConfig(const QString &config, bool regex) // CONFIG variable int t = 0; - foreach (const ProString &configValue, values(statics.strCONFIG)) { + const auto configValues = values(statics.strCONFIG); + for (const ProString &configValue : configValues) { if (re.exactMatch(configValue.toQString(m_tmp[t]))) return true; t ^= 1; @@ -1612,7 +1619,7 @@ bool QMakeEvaluator::isActiveConfig(const QString &config, bool regex) return true; // CONFIG variable - if (values(statics.strCONFIG).contains(ProString(config))) + if (values(statics.strCONFIG).contains(config)) return true; } @@ -1636,7 +1643,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::expandVariableReferences( tokPtr++; continue; } - // fallthrough + Q_FALLTHROUGH(); default: Q_ASSERT_X(false, "expandVariableReferences", "Unrecognized token"); break; @@ -1776,7 +1783,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateExpandFunction( } QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditional( - const QString &cond, const QString &where, int line) + const QStringRef &cond, const QString &where, int line) { VisitReturn ret = ReturnFalse; ProFile *pro = m_parser->parsedProBlock(cond, where, line, QMakeParser::TestGrammar); @@ -1793,8 +1800,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditional( QMakeEvaluator::VisitReturn QMakeEvaluator::checkRequirements(const ProStringList &deps) { ProStringList &failed = valuesRef(ProKey("QMAKE_FAILED_REQUIREMENTS")); - foreach (const ProString &dep, deps) { - VisitReturn vr = evaluateConditional(dep.toQString(), m_current.pro->fileName(), m_current.line); + for (const ProString &dep : deps) { + VisitReturn vr = evaluateConditional(dep.toQStringRef(), m_current.pro->fileName(), m_current.line); if (vr == ReturnError) return ReturnError; if (vr != ReturnTrue) @@ -1917,9 +1924,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFileChecked( { if (fileName.isEmpty()) return ReturnFalse; - QMakeEvaluator *ref = this; + const QMakeEvaluator *ref = this; do { - foreach (const ProFile *pf, ref->m_profileStack) + for (const ProFile *pf : ref->m_profileStack) if (pf->fileName() == fileName) { evalError(fL1S("Circular inclusion of %1.").arg(fileName)); return ReturnFalse; @@ -2031,7 +2038,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFileInto( *values = visitor.m_valuemapStack.top(); ProKey qiif("QMAKE_INTERNAL_INCLUDED_FILES"); ProStringList &iif = m_valuemapStack.first()[qiif]; - foreach (const ProString &ifn, values->value(qiif)) + const auto ifns = values->value(qiif); + for (const ProString &ifn : ifns) if (!iif.contains(ifn)) iif << ifn; return ReturnTrue; @@ -2112,7 +2120,7 @@ QString QMakeEvaluator::formatValue(const ProString &val, bool forceQuote) break; case 32: quote = true; - // fallthrough + Q_FALLTHROUGH(); default: ret += c; break; @@ -2130,7 +2138,7 @@ QString QMakeEvaluator::formatValueList(const ProStringList &vals, bool commas) { QString ret; - foreach (const ProString &str, vals) { + for (const ProString &str : vals) { if (!ret.isEmpty()) { if (commas) ret += QLatin1Char(','); @@ -2145,7 +2153,7 @@ QString QMakeEvaluator::formatValueListList(const QList<ProStringList> &lists) { QString ret; - foreach (const ProStringList &list, lists) { + for (const ProStringList &list : lists) { if (!ret.isEmpty()) ret += QLatin1String(", "); ret += formatValueList(list); diff --git a/src/linguist/shared/qmakeevaluator.h b/src/linguist/shared/qmakeevaluator.h index 7bfb363b7..5a430c14b 100644 --- a/src/linguist/shared/qmakeevaluator.h +++ b/src/linguist/shared/qmakeevaluator.h @@ -176,7 +176,7 @@ public: void setTemplate(); - ProStringList split_value_list(const QString &vals, const ProFile *source = 0); + ProStringList split_value_list(const QStringRef &vals, const ProFile *source = 0); VisitReturn expandVariableReferences(const ushort *&tokPtr, int sizeHint, ProStringList *ret, bool joined); QString currentFileName() const; @@ -215,7 +215,7 @@ public: ProStringList evaluateBuiltinExpand(int func_t, const ProKey &function, const ProStringList &args); VisitReturn evaluateBuiltinConditional(int func_t, const ProKey &function, const ProStringList &args); - VisitReturn evaluateConditional(const QString &cond, const QString &where, int line = -1); + VisitReturn evaluateConditional(const QStringRef &cond, const QString &where, int line = -1); #ifdef PROEVALUATOR_FULL VisitReturn checkRequirements(const ProStringList &deps); #endif @@ -223,7 +223,7 @@ public: void updateMkspecPaths(); void updateFeaturePaths(); - bool isActiveConfig(const QString &config, bool regex = false); + bool isActiveConfig(const QStringRef &config, bool regex = false); void populateDeps( const ProStringList &deps, const ProString &prefix, const ProStringList &suffixes, @@ -231,12 +231,16 @@ public: QHash<ProKey, QSet<ProKey> > &dependencies, ProValueMap &dependees, QMultiMap<int, ProString> &rootSet) const; + bool getMemberArgs(const ProKey &name, int srclen, const ProStringList &args, + int *start, int *end); + VisitReturn parseJsonInto(const QByteArray &json, const QString &into, ProValueMap *value); + VisitReturn writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode, bool exe, const QString &contents); #ifndef QT_BOOTSTRAPPED void runProcess(QProcess *proc, const QString &command) const; #endif - QByteArray getCommandOutput(const QString &args) const; + QByteArray getCommandOutput(const QString &args, int *exitCode) const; QMakeEvaluator *m_caller; #ifdef PROEVALUATOR_CUMULATIVE diff --git a/src/linguist/shared/qmakeglobals.cpp b/src/linguist/shared/qmakeglobals.cpp index 74334cc74..0b2a1ffce 100644 --- a/src/linguist/shared/qmakeglobals.cpp +++ b/src/linguist/shared/qmakeglobals.cpp @@ -106,7 +106,7 @@ QString QMakeGlobals::cleanSpec(QMakeCmdLineParserState &state, const QString &s QMakeGlobals::ArgumentReturn QMakeGlobals::addCommandLineArguments( QMakeCmdLineParserState &state, QStringList &args, int *pos) { - enum { ArgNone, ArgConfig, ArgSpec, ArgXSpec, ArgTmpl, ArgTmplPfx, ArgCache } argState = ArgNone; + enum { ArgNone, ArgConfig, ArgSpec, ArgXSpec, ArgTmpl, ArgTmplPfx, ArgCache, ArgQtConf } argState = ArgNone; for (; *pos < args.count(); (*pos)++) { QString arg = args.at(*pos); switch (argState) { @@ -131,8 +131,16 @@ QMakeGlobals::ArgumentReturn QMakeGlobals::addCommandLineArguments( case ArgCache: cachefile = args[*pos] = QDir::cleanPath(QDir(state.pwd).absoluteFilePath(arg)); break; + case ArgQtConf: + qtconf = args[*pos] = QDir::cleanPath(QDir(state.pwd).absoluteFilePath(arg)); + break; default: if (arg.startsWith(QLatin1Char('-'))) { + if (arg == QLatin1String("--")) { + state.extraargs = args.mid(*pos + 1); + *pos = args.size(); + return ArgumentsOk; + } if (arg == QLatin1String("-after")) state.after = true; else if (arg == QLatin1String("-config")) @@ -141,6 +149,8 @@ QMakeGlobals::ArgumentReturn QMakeGlobals::addCommandLineArguments( do_cache = false; else if (arg == QLatin1String("-cache")) argState = ArgCache; + else if (arg == QLatin1String("-qtconf")) + argState = ArgQtConf; else if (arg == QLatin1String("-platform") || arg == QLatin1String("-spec")) argState = ArgSpec; else if (arg == QLatin1String("-xplatform") || arg == QLatin1String("-xspec")) @@ -176,6 +186,12 @@ void QMakeGlobals::commitCommandLineArguments(QMakeCmdLineParserState &state) { if (!state.preconfigs.isEmpty()) state.precmds << (fL1S("CONFIG += ") + state.preconfigs.join(QLatin1Char(' '))); + if (!state.extraargs.isEmpty()) { + QString extra = fL1S("QMAKE_EXTRA_ARGS ="); + for (const QString &ea : qAsConst(state.extraargs)) + extra += QLatin1Char(' ') + QMakeEvaluator::quoteValue(ProString(ea)); + state.precmds << extra; + } precmds = state.precmds.join(QLatin1Char('\n')); if (!state.postconfigs.isEmpty()) state.postcmds << (fL1S("CONFIG += ") + state.postconfigs.join(QLatin1Char(' '))); @@ -245,9 +261,9 @@ QStringList QMakeGlobals::splitPathList(const QString &val) const QStringList ret; if (!val.isEmpty()) { QDir bdir; - QStringList vals = val.split(dirlist_sep); + const QStringList vals = val.split(dirlist_sep); ret.reserve(vals.length()); - foreach (const QString &it, vals) + for (const QString &it : vals) ret << QDir::cleanPath(bdir.absoluteFilePath(it)); } return ret; @@ -311,7 +327,8 @@ bool QMakeGlobals::initProperties() QT_PCLOSE(proc); } #endif - foreach (QByteArray line, data.split('\n')) { + const auto lines = data.split('\n'); + for (QByteArray line : lines) { int off = line.indexOf(':'); if (off < 0) // huh? continue; diff --git a/src/linguist/shared/qmakeglobals.h b/src/linguist/shared/qmakeglobals.h index d3074f9fe..756f69dd9 100644 --- a/src/linguist/shared/qmakeglobals.h +++ b/src/linguist/shared/qmakeglobals.h @@ -85,7 +85,7 @@ class QMAKE_EXPORT QMakeCmdLineParserState public: QMakeCmdLineParserState(const QString &_pwd) : pwd(_pwd), after(false) {} QString pwd; - QStringList precmds, preconfigs, postcmds, postconfigs; + QStringList precmds, preconfigs, postcmds, postconfigs, extraargs; bool after; void flush() { after = false; } @@ -107,6 +107,7 @@ public: QString qmake_abslocation; QStringList qmake_args; + QString qtconf; QString qmakespec, xqmakespec; QString user_template, user_template_prefix; QString precmds, postcmds; diff --git a/src/linguist/shared/qmakeparser.cpp b/src/linguist/shared/qmakeparser.cpp index 874b39df1..6f0047bf5 100644 --- a/src/linguist/shared/qmakeparser.cpp +++ b/src/linguist/shared/qmakeparser.cpp @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE ProFileCache::~ProFileCache() { - foreach (const Entry &ent, parsed_files) + for (const Entry &ent : qAsConst(parsed_files)) if (ent.pro) ent.pro->deref(); } @@ -165,7 +165,7 @@ QMakeParser::QMakeParser(ProFileCache *cache, QMakeVfs *vfs, QMakeParserHandler ProFile *QMakeParser::parsedProFile(const QString &fileName, ParseFlags flags) { ProFile *pro; - if ((flags & ParseUseCache) && m_cache) { + if ((flags & (ParseUseCache|ParseOnlyCached)) && m_cache) { ProFileCache::Entry *ent; #ifdef PROPARSER_THREAD_SAFE QMutexLocker locker(&m_cache->mutex); @@ -187,7 +187,7 @@ ProFile *QMakeParser::parsedProFile(const QString &fileName, ParseFlags flags) #endif if ((pro = ent->pro)) pro->ref(); - } else { + } else if (!(flags & ParseOnlyCached)) { ent = &m_cache->parsed_files[fileName]; #ifdef PROPARSER_THREAD_SAFE ent->locker = new ProFileCache::Entry::Locker; @@ -212,19 +212,23 @@ ProFile *QMakeParser::parsedProFile(const QString &fileName, ParseFlags flags) ent->locker = 0; } #endif + } else { + pro = 0; } - } else { + } else if (!(flags & ParseOnlyCached)) { pro = new ProFile(fileName); if (!read(pro, flags)) { delete pro; pro = 0; } + } else { + pro = 0; } return pro; } ProFile *QMakeParser::parsedProBlock( - const QString &contents, const QString &name, int line, SubGrammar grammar) + const QStringRef &contents, const QString &name, int line, SubGrammar grammar) { ProFile *pro = new ProFile(name); read(pro, contents, line, grammar); @@ -247,7 +251,7 @@ bool QMakeParser::read(ProFile *pro, ParseFlags flags) fL1S("Cannot read %1: %2").arg(pro->fileName(), errStr)); return false; } - read(pro, content, 1, FullGrammar); + read(pro, QStringRef(&content), 1, FullGrammar); return true; } @@ -289,7 +293,7 @@ void QMakeParser::finalizeHashStr(ushort *buf, uint len) buf[-2] = (ushort)(hash >> 16); } -void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar grammar) +void QMakeParser::read(ProFile *pro, const QStringRef &in, int line, SubGrammar grammar) { m_proFile = pro; m_lineNo = line; @@ -337,8 +341,8 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra QStack<ParseCtx> xprStack; xprStack.reserve(10); - // We rely on QStrings being null-terminated, so don't maintain a global end pointer. const ushort *cur = (const ushort *)in.unicode(); + const ushort *inend = cur + in.length(); m_canElse = false; freshLine: m_state = StNew; @@ -421,7 +425,7 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra int indent; if (context == CtxPureValue) { - end = (const ushort *)in.unicode() + in.length(); + end = inend; cptr = 0; lineCont = false; indent = 0; // just gcc being stupid @@ -433,24 +437,30 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra // First, skip leading whitespace for (indent = 0; ; ++cur, ++indent) { + if (cur == inend) { + cur = 0; + goto flushLine; + } c = *cur; if (c == '\n') { ++cur; goto flushLine; - } else if (!c) { - cur = 0; - goto flushLine; - } else if (c != ' ' && c != '\t' && c != '\r') { - break; } + if (c != ' ' && c != '\t' && c != '\r') + break; } // Then strip comments. Yep - no escaping is possible. for (cptr = cur;; ++cptr) { + if (cptr == inend) { + end = cptr; + break; + } c = *cptr; if (c == '#') { - for (end = cptr; (c = *++cptr);) { - if (c == '\n') { + end = cptr; + while (++cptr < inend) { + if (*cptr == '\n') { ++cptr; break; } @@ -463,10 +473,6 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra } break; } - if (!c) { - end = cptr; - break; - } if (c == '\n') { end = cptr++; break; @@ -1218,7 +1224,7 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg bool QMakeParser::resolveVariable(ushort *xprPtr, int tlen, int needSep, ushort **ptr, ushort **buf, QString *xprBuff, ushort **tokPtr, QString *tokBuff, - const ushort *cur, const QString &in) + const ushort *cur, const QStringRef &in) { QString out; m_tmp.setRawData((const QChar *)xprPtr, tlen); diff --git a/src/linguist/shared/qmakeparser.h b/src/linguist/shared/qmakeparser.h index e6db67e5e..0b25ade90 100644 --- a/src/linguist/shared/qmakeparser.h +++ b/src/linguist/shared/qmakeparser.h @@ -78,7 +78,8 @@ public: enum ParseFlag { ParseDefault = 0, ParseUseCache = 1, - ParseReportMissing = 2 + ParseOnlyCached = 2, + ParseReportMissing = 4 }; Q_DECLARE_FLAGS(ParseFlags, ParseFlag) @@ -87,7 +88,7 @@ public: enum SubGrammar { FullGrammar, TestGrammar, ValueGrammar }; // fileName is expected to be absolute and cleanPath()ed. ProFile *parsedProFile(const QString &fileName, ParseFlags flags = ParseDefault); - ProFile *parsedProBlock(const QString &contents, const QString &name, int line = 0, + ProFile *parsedProBlock(const QStringRef &contents, const QString &name, int line = 0, SubGrammar grammar = FullGrammar); void discardFileFromCache(const QString &fileName); @@ -130,7 +131,7 @@ private: }; bool read(ProFile *pro, ParseFlags flags); - void read(ProFile *pro, const QString &content, int line, SubGrammar grammar); + void read(ProFile *pro, const QStringRef &content, int line, SubGrammar grammar); ALWAYS_INLINE void putTok(ushort *&tokPtr, ushort tok); ALWAYS_INLINE void putBlockLen(ushort *&tokPtr, uint len); @@ -141,7 +142,7 @@ private: ALWAYS_INLINE bool resolveVariable(ushort *xprPtr, int tlen, int needSep, ushort **ptr, ushort **buf, QString *xprBuff, ushort **tokPtr, QString *tokBuff, - const ushort *cur, const QString &in); + const ushort *cur, const QStringRef &in); void finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount); void finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int argc); void warnOperator(const char *msg); diff --git a/src/linguist/shared/qph.cpp b/src/linguist/shared/qph.cpp index 26b511201..da5d20e2a 100644 --- a/src/linguist/shared/qph.cpp +++ b/src/linguist/shared/qph.cpp @@ -178,7 +178,7 @@ int initQPH() Translator::FileFormat format; format.extension = QLatin1String("qph"); - format.description = FMT::tr("Qt Linguist 'Phrase Book'"); + format.untranslatedDescription = QT_TRANSLATE_NOOP("FMT", "Qt Linguist 'Phrase Book'"); format.fileType = Translator::FileFormat::TranslationSource; format.priority = 0; format.loader = &loadQPH; diff --git a/src/linguist/shared/translator.cpp b/src/linguist/shared/translator.cpp index b20b412ba..f583b623a 100644 --- a/src/linguist/shared/translator.cpp +++ b/src/linguist/shared/translator.cpp @@ -35,12 +35,8 @@ #include <stdio.h> #ifdef Q_OS_WIN // required for _setmode, to avoid _O_TEXT streams... -# ifdef Q_OS_WINCE -# include <stdlib.h> -# else # include <io.h> // for _setmode # include <fcntl.h> // for _O_BINARY -# endif #endif #include <QtCore/QDebug> @@ -279,11 +275,7 @@ bool Translator::load(const QString &filename, ConversionData &cd, const QString if (filename.isEmpty() || filename == QLatin1String("-")) { #ifdef Q_OS_WIN // QFile is broken for text files -# ifdef Q_OS_WINCE - ::_setmode(stdin, _O_BINARY); -# else ::_setmode(0, _O_BINARY); -# endif #endif if (!file.open(stdin, QIODevice::ReadOnly)) { cd.appendError(QString::fromLatin1("Cannot open stdin!? (%1)") @@ -323,11 +315,7 @@ bool Translator::save(const QString &filename, ConversionData &cd, const QString if (filename.isEmpty() || filename == QLatin1String("-")) { #ifdef Q_OS_WIN // QFile is broken for text files -# ifdef Q_OS_WINCE - ::_setmode(stdout, _O_BINARY); -# else ::_setmode(1, _O_BINARY); -# endif #endif if (!file.open(stdout, QIODevice::WriteOnly)) { cd.appendError(QString::fromLatin1("Cannot open stdout!? (%1)") diff --git a/src/linguist/shared/translator.h b/src/linguist/shared/translator.h index be412180a..ff6bd9578 100644 --- a/src/linguist/shared/translator.h +++ b/src/linguist/shared/translator.h @@ -180,9 +180,11 @@ public: typedef bool (*SaveFunction)(const Translator &, QIODevice &out, ConversionData &data); typedef bool (*LoadFunction)(Translator &, QIODevice &in, ConversionData &data); struct FileFormat { - FileFormat() : loader(0), saver(0), priority(-1) {} + FileFormat() : untranslatedDescription(nullptr), loader(0), saver(0), priority(-1) {} QString extension; // such as "ts", "xlf", ... - QString description; // human-readable description + const char *untranslatedDescription; + // human-readable description + QString description() const { return FMT::tr(untranslatedDescription); } LoadFunction loader; SaveFunction saver; enum FileType { TranslationSource, TranslationBinary } fileType; diff --git a/src/linguist/shared/ts.cpp b/src/linguist/shared/ts.cpp index fc71ededb..cfbbd4384 100644 --- a/src/linguist/shared/ts.cpp +++ b/src/linguist/shared/ts.cpp @@ -687,7 +687,7 @@ int initTS() format.extension = QLatin1String("ts"); format.fileType = Translator::FileFormat::TranslationSource; format.priority = 0; - format.description = FMT::tr("Qt translation sources"); + format.untranslatedDescription = QT_TRANSLATE_NOOP("FMT", "Qt translation sources"); format.loader = &loadTS; format.saver = &saveTS; Translator::registerFileFormat(format); diff --git a/src/linguist/shared/xliff.cpp b/src/linguist/shared/xliff.cpp index 1478cd42c..025b222b4 100644 --- a/src/linguist/shared/xliff.cpp +++ b/src/linguist/shared/xliff.cpp @@ -833,7 +833,7 @@ int initXLIFF() { Translator::FileFormat format; format.extension = QLatin1String("xlf"); - format.description = FMT::tr("XLIFF localization files"); + format.untranslatedDescription = QT_TRANSLATE_NOOP("FMT", "XLIFF localization files"); format.fileType = Translator::FileFormat::TranslationSource; format.priority = 1; format.loader = &loadXLIFF; diff --git a/src/qconfig/feature.cpp b/src/qconfig/feature.cpp deleted file mode 100644 index 71cb8816f..000000000 --- a/src/qconfig/feature.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ - -#include "feature.h" -#include <QTextStream> -#include <QRegExp> -#include <QLibraryInfo> -#include <QFileInfo> -#include <QApplication> -#include <QPalette> - -QT_BEGIN_NAMESPACE - -QMap<QString, Feature*> Feature::instances; - -Feature* Feature::getInstance(const QString &key) -{ - QString ukey = key.toUpper(); - if (!instances.contains(ukey)) - instances[ukey] = new Feature(ukey); - return instances[ukey]; -} - -Feature::~Feature() -{ - delete d; -} - -void Feature::clear() -{ - foreach (Feature *f, instances.values()) - delete f; - instances.clear(); -} - -static QString listToHtml(const QString &title, const QStringList &list) -{ - if (list.isEmpty()) - return QString(); - - QString str; - QTextStream stream(&str); - - stream << "<h3>" << title << ":</h3>"; - stream << "<ul>"; - foreach (QString l, list) - stream << "<li>" << l << "</li>"; - stream << "</ul>"; - - return str; -} - -static QString listToHtml(const QString &title, const QList<Feature*> &list) -{ - QStringList stringlist; - foreach (Feature *f, list) { - QString s("[%3] <a href=\"feature://%1\">%2</a>"); - s = s.arg(f->key()).arg(f->key()); - s = s.arg(f->selectable() && f->enabled() ? "On" : "Off"); - stringlist << s; - } - return listToHtml(title, stringlist); -} - -static QString linkify(const QString &src) -{ - static QRegExp classRegexp("\\b(Q[\\w]+)"); - QString docRoot = QLibraryInfo::location(QLibraryInfo::DocumentationPath); - QString result = src; - int pos = 0; - while ((pos = classRegexp.indexIn(result, pos)) != -1) { - QString className = classRegexp.cap(1); - QString file = docRoot + "/html/" + className.toLower() + ".html"; - QFileInfo info(file); - if (info.isFile()) { - QString link = QString("<a href=\"file://%1\">%2</a>") - .arg(file).arg(className); - result.replace(pos, className.length(), link); - pos += link.length(); - } else { - pos += className.length(); - } - } - - return result; -} - -QString Feature::toHtml() const -{ - QString str; - QTextStream stream(&str); - - const QString linkColor = QApplication::palette().color(QPalette::Link).name(); - stream << "<h2><font size=\"+2\" color=\"" << linkColor << "\">" - << key() << "</font></h2>" - << "<h2><font size=\"+2\">" << title() << "</font></h2>"; - if (!description().isEmpty()) - stream << "<p>" << description() << "</p>"; - stream << listToHtml("Section", QStringList(section())) - << listToHtml("Requires", dependencies()) - << listToHtml("Required for", supports()) - << listToHtml("See also", relations()); - - return linkify(str); -} - -Feature::Feature(const QString &key) : d(new FeaturePrivate(key)) {} - -void Feature::setTitle(const QString &title) -{ - d->title = title; -} - -void Feature::setSection(const QString §ion) -{ - d->section = section; -} - -void Feature::setDescription(const QString &description) -{ - d->description = description; -} - -void Feature::addRelation(const QString &key) -{ - d->relations.insert(getInstance(key)); -} - -void Feature::setRelations(const QStringList &keys) -{ - foreach(QString key, keys) - if (key != "???") - addRelation(key); -} - -QList<Feature*> Feature::relations() const -{ - return d->relations.toList(); -} - -void Feature::addDependency(const QString &key) -{ - Feature *f = getInstance(key); - d->dependencies.insert(f); - f->d->supports.insert(this); -} - -void Feature::setDependencies(const QStringList &keys) -{ - foreach(QString key, keys) - addDependency(key); -} - -QList<Feature*> Feature::dependencies() const -{ - return d->dependencies.toList(); -} - -QList<Feature*> Feature::supports() const -{ - return d->supports.toList(); -} - -/* - Returns a html formatted detailed description of this Feature. -*/ -QString Feature::getDocumentation() const -{ - return QString() + "<h2>" + d->title + "</h2>"; - -} - -void Feature::setEnabled(bool on) -{ - if (on == d->enabled) - return; - - d->enabled = on; - foreach (Feature *f, supports()) - f->updateSelectable(); - emit changed(); -} - -/* - Update whether this feature should be selectable. - A feature is selectable if all its dependencies are enabled. -*/ -void Feature::updateSelectable() -{ - bool selectable = true; - foreach (Feature *f, dependencies()) - if (!f->selectable() || !f->enabled()) - selectable = false; - if (selectable != d->selectable) { - d->selectable = selectable; - foreach (Feature *f, supports()) - f->updateSelectable(); - emit changed(); - } -} - -QT_END_NAMESPACE diff --git a/src/qconfig/feature.h b/src/qconfig/feature.h deleted file mode 100644 index d120ffcee..000000000 --- a/src/qconfig/feature.h +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ - -#ifndef FEATURE_H -#define FEATURE_H - -#include <QString> -#include <QStringList> -#include <QMap> -#include <QSet> -#include <QList> - -QT_BEGIN_NAMESPACE - -class Feature; - -class FeaturePrivate -{ -public: - FeaturePrivate(const QString &k) - : key(k), enabled(true), selectable(true) {}; - - const QString key; - QString section; - QString title; - QString description; - QSet<Feature*> dependencies; - QSet<Feature*> supports; // features who depends on this one - QSet<Feature*> relations; - bool enabled; - bool selectable; -}; - -class Feature : public QObject -{ - Q_OBJECT - -public: - static Feature* getInstance(const QString &key); - static void clear(); - -public: - QString key() const { return d->key; } - - void setTitle(const QString &title); - QString title() const { return d->title; } - - void setSection(const QString §ion); - QString section() const { return d->section; } - - void setDescription(const QString &description); - QString description() const { return d->description; }; - - void addRelation(const QString &key); - void setRelations(const QStringList &keys); - QList<Feature*> relations() const; - - void addDependency(const QString &dependency); - void setDependencies(const QStringList &dependencies); - QList<Feature*> dependencies() const; - - QList<Feature*> supports() const; - QString getDocumentation() const; - - void setEnabled(bool on); - bool enabled() const { return d->enabled; }; - - bool selectable() const { return d->selectable; } - - QString toHtml() const; - - ~Feature(); - -signals: - void changed(); - -private: - Feature(const QString &key); - void updateSelectable(); - - static QMap<QString, Feature*> instances; - FeaturePrivate *d; -}; - -QT_END_NAMESPACE - -#endif // FEATURE_H diff --git a/src/qconfig/featuretreemodel.cpp b/src/qconfig/featuretreemodel.cpp deleted file mode 100644 index 307c90113..000000000 --- a/src/qconfig/featuretreemodel.cpp +++ /dev/null @@ -1,438 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ - -#include "featuretreemodel.h" -#include "feature.h" -#include <QPalette> -#include <QColor> -#include <QApplication> -#include <QtDebug> - -QT_BEGIN_NAMESPACE - -class Node -{ -public: - Node(Feature *f, Node *p = 0) : feature(f), parent(p) {} - ~Node(); - Node* find(const Feature *child) const; - bool contains(const Feature *child) const { return find(child) != 0; } - bool insert(Node *n); - - Feature *feature; - Node *parent; - QList<Node*> children; // maybe convert to Map to get keys sorted -}; - -Node::~Node() -{ - while (!children.isEmpty()) - delete children.takeFirst(); -} - -Node* Node::find(const Feature *f) const -{ - if (this->feature == f) - return const_cast<Node*>(this); - - foreach (Node *n, children) - if (Node *m = n->find(f)) - return m; - - return 0; -} - -static bool nodePtrLessThan(const Node *n1, const Node *n2) -{ - return (n1->feature->key() < n2->feature->key()); -} - -/* - Try insert \a n into the tree with this node as root. - n is inserted as a child if it has a dependency to this node. - Returns true if child is inserted into the tree, false otherwise. -*/ -bool Node::insert(Node *n) -{ - Feature *f = const_cast<Feature*>(n->feature); - if (feature->supports().contains(f)) { - children.append(n); - qSort(children.begin(), children.end(), nodePtrLessThan); - n->parent = this; - return true; - } - foreach (Node *child, children) - if (child->insert(n)) - return true; - return false; -} - -static bool isSection(const QModelIndex &index) -{ - return index.isValid() && (index.internalId() == 0); -} - -FeatureTreeModel::FeatureTreeModel(QObject *parent) - : QAbstractItemModel(parent) -{ -} - -FeatureTreeModel::~FeatureTreeModel() -{ - foreach (QString section, sections.keys()) - while (!sections[section].isEmpty()) - delete sections[section].takeFirst(); -} - -/* - Returns true if the model already contains \a in \a section, false otherwise. -*/ -bool FeatureTreeModel::contains(const QString §ion, const Feature *f) const -{ - return (find(section, f) != 0); -} - -Node* FeatureTreeModel::find(const QString §ion, const Feature *f) const -{ - QList<Node*> roots = sections[section]; - foreach (Node *root, roots) - if (Node *n = root->find(f)) - return n; - return 0; -} - -/* - Add new \a feature to the tree. - When all feature is added, buildTree() must be called to build the - dependency tree. -*/ -void FeatureTreeModel::addFeature(Feature *feature) -{ - const QString section = feature->section(); - Q_ASSERT(!contains(section, feature)); - - connect(feature, SIGNAL(changed()), this, SLOT(featureChanged())); - - Node *node = new Node(feature, 0); - - // try insert any toplevel nodes as child of this one - foreach (Node *n, sections[section]) - if (node->insert(n)) - sections[section].removeAll(n); - - // try insert this node as a child of any existing node - foreach (Node *n, sections[section]) - if (n->insert(node)) { - emit layoutChanged(); - return; - } - - // not a child, insert as a toplevel node - sections[section].append(node); - qSort(sections[section].begin(), sections[section].end(), nodePtrLessThan); - emit layoutChanged(); -} - -QModelIndex FeatureTreeModel::createIndex(int row, int column, - const QModelIndex &parent, - const Node *node) const -{ - QModelIndex index = QAbstractItemModel::createIndex(row, column, - (void*)node); - if (parent.isValid()) - parentMap[index] = parent; - if (node) - featureIndexMap[node->feature] = index; - return index; -} - -QModelIndex FeatureTreeModel::index(int row, int column, - const QModelIndex &parent) const -{ - if (!parent.isValid()) { // index is a section - if (row < sections.size() && column == 0) - return QAbstractItemModel::createIndex(row, column); - return QModelIndex(); - } - - if (isSection(parent)) { // index is a toplevel feature - const int parentRow = parent.row(); - if (parentRow < sections.size()) { - QString section = sections.keys().at(parentRow); - QList<Node*> nodes = sections[section]; - if (row < nodes.size() && column < 2) - return createIndex(row, column, parent, nodes.at(row)); - } - return QModelIndex(); - } - - // parent is a feature - Node *parentNode = static_cast<Node*>(parent.internalPointer()); - QList<Node*> children = parentNode->children; - if (row < children.size() && column < 2) - return createIndex(row, column, parent, children.at(row)); - - return QModelIndex(); -} - -QModelIndex FeatureTreeModel::index(const QModelIndex &parent, - const Feature *feature) const -{ - const int rows = rowCount(parent); - for (int i = 0; i < rows; ++i) { - QModelIndex child = index(i, 0, parent); - Node *node = static_cast<Node*>(child.internalPointer()); - if (node && node->feature == feature) - return child; - QModelIndex childSearch = index(child, feature); - if (childSearch.isValid()) - return childSearch; - } - return QModelIndex(); -} - -QModelIndex FeatureTreeModel::index(const Feature *feature) const -{ - if (featureIndexMap.contains(feature)) - return featureIndexMap.value(feature); - - // exhaustive search - int sectionRow = sections.keys().indexOf(feature->section()); - QModelIndex sectionIndex = index(sectionRow, 0, QModelIndex()); - - return index(sectionIndex, feature); -} - -QModelIndex FeatureTreeModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - return QModelIndex(); - - if (parentMap.contains(index)) - return parentMap.value(index); - return QModelIndex(); -} - -int FeatureTreeModel::rowCount(const QModelIndex &parent) const -{ - if (!parent.isValid()) - return sections.size(); - - if (isSection(parent)) { - const QString section = sections.keys().at(parent.row()); - return sections[section].size(); - } - - const Node *node = static_cast<Node*>(parent.internalPointer()); - return node->children.size(); -} - -int FeatureTreeModel::columnCount(const QModelIndex &parent) const -{ -#if 0 - if (!parent.isValid()) - return 0; - - if (isSection(parent)) - return 1; -#endif - Q_UNUSED(parent); - return 2; // Feature: [key, name] -} - -QVariant FeatureTreeModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - const Node *node = static_cast<Node*>(index.internalPointer()); - - switch (role) { - case Qt::DisplayRole: { - if (node == 0) // index is a section - return sections.keys().at(index.row()); - if (index.column() == 0) - return node->feature->key(); - Q_ASSERT(index.column() == 1); - return node->feature->title(); - } - case Qt::CheckStateRole: { - if (node && index.column() == 0) - return (node->feature->enabled() ? - Qt::Checked : Qt::Unchecked); - break; - } - case Qt::TextColorRole: { - if (node && index.column() == 0) // feature key - if (node->feature->selectable()) - return QApplication::palette().color(QPalette::Link); - break; - } - case Qt::TextAlignmentRole: - case Qt::BackgroundColorRole: - case Qt::FontRole: - case Qt::ToolTipRole: // TODO - case Qt::StatusTipRole: // TODO - case Qt::WhatsThisRole: // TODO - case Qt::DecorationRole: - case Qt::EditRole: - default: - break; - } - return QVariant(); -} - -bool FeatureTreeModel::setData(const QModelIndex &index, - const QVariant &value, int role) -{ - if (!index.isValid()) - return false; - - Node *node = static_cast<Node*>(index.internalPointer()); - if (!node) - return false; - - if (role == Qt::CheckStateRole) { - Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt()); - if (state == Qt::Checked) - node->feature->setEnabled(true); - else if (state == Qt::Unchecked) - node->feature->setEnabled(false); - emit dataChanged(index, index); - return true; - } - return false; -} - -Qt::ItemFlags FeatureTreeModel::flags(const QModelIndex &index) const -{ - if (!index.isValid() || index.internalPointer() == 0) - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; - - const Node *node = static_cast<Node*>(index.internalPointer()); - const Feature *feature = node->feature; - Qt::ItemFlags flags = Qt::ItemIsUserCheckable | Qt::ItemIsSelectable; - - if (feature->selectable()) - flags |= Qt::ItemIsEnabled; - - return flags; -} - -QVariant FeatureTreeModel::headerData(int section, Qt::Orientation orientation, - int role) const -{ - if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { - if (section == 0) - return QString("Id"); - else if (section == 1) - return QString("Name"); - } - - return QVariant(); -} - -Feature* FeatureTreeModel::getFeature(const QModelIndex &index) const -{ - if (!index.isValid()) - return 0; - if (isSection(index)) - return 0; - Node *node = static_cast<Node*>(index.internalPointer()); - return const_cast<Feature*>(node->feature); -} - -void FeatureTreeModel::featureChanged() -{ - Feature *feature = qobject_cast<Feature*>(sender()); - if (feature) { - QModelIndex featureIndex = index(feature); - emit dataChanged(featureIndex, featureIndex); - } else { - emit layoutChanged(); - } -} - -void FeatureTreeModel::readConfig(QTextStream &stream) -{ - static QRegExp regexp("\\s*#\\s*define\\s+QT_NO_(\\S+)\\s*"); - - while (!stream.atEnd()) { - QString line = stream.readLine(); - if (regexp.exactMatch(line)) { - Feature *f = Feature::getInstance(regexp.cap(1)); - f->setEnabled(false); - } - } -} -/* - Search for all disabled child features of \a parent. - Returns a list of feature keys for the disabled items. -*/ -QStringList FeatureTreeModel::findDisabled(const QModelIndex &parent) const -{ - QStringList stringList; - - const int rows = rowCount(parent); - for (int i = 0; i < rows; ++i) { - QModelIndex child = index(i, 0, parent); - Node *node = static_cast<Node*>(child.internalPointer()); - if (node && node->feature && !node->feature->enabled()) - stringList << node->feature->key(); - stringList << findDisabled(child); - } - return stringList; -} - -void FeatureTreeModel::writeConfig(QTextStream &stream) const -{ - const int sectionCount = rowCount(QModelIndex()); - - for (int i = 0; i < sectionCount; ++i) { - QModelIndex section = index(i, 0, QModelIndex()); - QStringList disabled = findDisabled(section); - if (disabled.size() > 0) { - stream << '\n' << "/* " << sections.keys().at(i) << " */" << '\n'; - foreach (QString feature, disabled) - stream << "#ifndef QT_NO_" << feature << '\n' - << "# define QT_NO_" << feature << '\n' - << "#endif" << '\n'; - } - } -} - -void FeatureTreeModel::clear() -{ - Feature::clear(); - sections.clear(); - parentMap.clear(); - featureIndexMap.clear(); - emit layoutChanged(); -} - -QT_END_NAMESPACE diff --git a/src/qconfig/featuretreemodel.h b/src/qconfig/featuretreemodel.h deleted file mode 100644 index fa145609a..000000000 --- a/src/qconfig/featuretreemodel.h +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ - -#ifndef FEATURETREEMODEL_H -#define FEATURETREEMODEL_H - -#include <QAbstractItemModel> -#include <QMap> -#include <QHash> -#include <QTextStream> - -QT_BEGIN_NAMESPACE - -class Feature; -class Node; - -uint qHash(const QModelIndex&); - -class FeatureTreeModel : public QAbstractItemModel -{ - Q_OBJECT - -public: - FeatureTreeModel(QObject *parent = 0); - ~FeatureTreeModel(); - - void clear(); - - QVariant data(const QModelIndex &index, int role) const; - bool setData(const QModelIndex &index, const QVariant &value, int role); - Qt::ItemFlags flags(const QModelIndex &index) const; - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const; - QModelIndex index(int row, int column, - const QModelIndex &parent = QModelIndex()) const; - QModelIndex index(const Feature *feature) const; - QModelIndex parent(const QModelIndex &index) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - - void addFeature(Feature *feature); - Feature* getFeature(const QModelIndex &index) const; - - void readConfig(QTextStream &stream); - void writeConfig(QTextStream &stream) const; - -public slots: - void featureChanged(); - -private: - QModelIndex createIndex(int row, int column, - const QModelIndex &parent, - const Node *feature) const; - QModelIndex index(const QModelIndex &parent, const Feature *feature) const; - bool contains(const QString §ion, const Feature *f) const; - Node* find(const QString §ion, const Feature *f) const; - QStringList findDisabled(const QModelIndex &parent) const; - - QMap<QString, QList<Node*> > sections; - mutable QHash<QModelIndex, QModelIndex> parentMap; - mutable QHash<const Feature*, QModelIndex> featureIndexMap; -}; - -QT_END_NAMESPACE - -#endif // FEATURETREEMODEL_H diff --git a/src/qconfig/graphics.h b/src/qconfig/graphics.h deleted file mode 100644 index 8547ee858..000000000 --- a/src/qconfig/graphics.h +++ /dev/null @@ -1,182 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ - -#ifndef GRAPHICS_H -#define GRAPHICS_H - -static const char *logo_xpm[] = { -/* width height ncolors chars_per_pixel */ -"50 50 17 1", -/* colors */ -" c #000000", -". c #495808", -"X c #2A3304", -"o c #242B04", -"O c #030401", -"+ c #9EC011", -"@ c #93B310", -"# c #748E0C", -"$ c #A2C511", -"% c #8BA90E", -"& c #99BA10", -"* c #060701", -"= c #181D02", -"- c #212804", -"; c #61770A", -": c #0B0D01", -"/ c None", -/* pixels */ -"/$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$/", -"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", -"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", -"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", -"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", -"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", -"$$$$$$$$$$$$$$$$$$$$$$$+++$$$$$$$$$$$$$$$$$$$$$$$$", -"$$$$$$$$$$$$$$$$$$$@;.o=::=o.;@$$$$$$$$$$$$$$$$$$$", -"$$$$$$$$$$$$$$$$+#X* **X#+$$$$$$$$$$$$$$$$", -"$$$$$$$$$$$$$$$#oO* O **o#+$$$$$$$$$$$$$$", -"$$$$$$$$$$$$$&.* OO O*.&$$$$$$$$$$$$$", -"$$$$$$$$$$$$@XOO * OO X&$$$$$$$$$$$$", -"$$$$$$$$$$$@XO OO O **:::OOO OOO X@$$$$$$$$$$$", -"$$$$$$$$$$&XO O-;#@++@%.oOO X&$$$$$$$$$$", -"$$$$$$$$$$.O : *-#+$$$$$$$$+#- : O O*.$$$$$$$$$$", -"$$$$$$$$$#*OO O*.&$$$$$$$$$$$$+.OOOO **#$$$$$$$$$", -"$$$$$$$$+-OO O *;$$$$$$$$$$$&$$$$;* o+$$$$$$$$", -"$$$$$$$$#O* O .+$$$$$$$$$$@X;$$$+.O *#$$$$$$$$", -"$$$$$$$$X* -&$$$$$$$$$$@- :;$$$&- OX$$$$$$$$", -"$$$$$$$@*O *O#$$$$$$$$$$@oOO**;$$$# O*%$$$$$$$", -"$$$$$$$; -+$$$$$$$$$@o O OO ;+$$-O *;$$$$$$$", -"$$$$$$$. ;$$$$$$$$$@-OO OO X&$$;O .$$$$$$$", -"$$$$$$$o *#$$$$$$$$@o O O O-@$$$#O *o$$$$$$$", -"$$$$$$+= *@$$$$$$$@o* OO -@$$$$&: =$$$$$$$", -"$$$$$$+: :+$$$$$$@- *-@$$$$$$: :+$$$$$$", -"$$$$$$+: :+$$$$$@o* O *-@$$$$$$: :+$$$$$$", -"$$$$$$$= :@$$$$@o*OOO -@$$$$@: =+$$$$$$", -"$$$$$$$- O%$$$@o* O O O O-@$$$#* OX$$$$$$$", -"$$$$$$$. O *O;$$&o O*O* *O -@$$; O.$$$$$$$", -"$$$$$$$;* Oo+$$;O*O:OO-- Oo@+= *;$$$$$$$", -"$$$$$$$@* O O#$$$;*OOOo@@-O Oo;O* **@$$$$$$$", -"$$$$$$$$X* OOO-+$$$;O o@$$@- O O OX$$$$$$$$", -"$$$$$$$$#* * O.$$$$;X@$$$$@-O O O#$$$$$$$$", -"$$$$$$$$+oO O OO.+$$+&$$$$$$@-O o+$$$$$$$$", -"$$$$$$$$$#* **.&$$$$$$$$$$@o OO:#$$$$$$$$$", -"$$$$$$$$$+. O* O-#+$$$$$$$$+;O OOO:@$$$$$$$$$", -"$$$$$$$$$$&X *O -;#@++@#;=O O -@$$$$$$$$", -"$$$$$$$$$$$&X O O*O::::O OO Oo@$$$$$$$", -"$$$$$$$$$$$$@XOO OO O*X+$$$$$$", -"$$$$$$$$$$$$$&.* ** O :: *:#$$$$$$$", -"$$$$$$$$$$$$$$$#o*OO O Oo#@-OOO=#$$$$$$$$", -"$$$$$$$$$$$$$$$$+#X:* * O**X#+$$@-*:#$$$$$$$$$", -"$$$$$$$$$$$$$$$$$$$%;.o=::=o.#@$$$$$$@X#$$$$$$$$$$", -"$$$$$$$$$$$$$$$$$$$$$$$$+++$$$$$$$$$$$+$$$$$$$$$$$", -"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", -"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", -"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", -"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", -"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", -"/$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$/", -}; - -static const char *expanded_xpm[] = { -"32 32 3 1", -" c None", -"# c #000000", -"a c #0000c0", -" ## ", -" ## ", -" #############aaaaaaaaaaaaa ", -" ## # ", -" ## # ", -" ## # ", -" ## # ", -" ## # ", -" ## # ", -" ## #aaaaaaaaaaaaa ", -" ## ", -" ## ", -" ## ", -" ## ", -" ## ", -" #############aaaaaaaaaaaaa ", -" ## # ", -" ## # ", -" ## # ", -" ## # ", -" ## # ", -" ## #aaaaaaaaaaaaa ", -" ## ", -" ## ", -" ## ", -" ## ", -" ## ", -" #############aaaaaaaaaaaaa ", -" ## # ", -" ## # ", -" ## # ", -" ## # "}; - -static const char *collapsed_xpm[] = { -"32 32 3 1", -" c None", -"# c #000000", -"a c #0000c0", -" ## ", -" ## ", -" ##aaaaaaaaaaaaaaaaaa ", -" ## ", -" ## ", -" ## ", -" ## ", -" ## ", -" ## ", -" ## ", -" ##aaaaaaaaaaaaaaaaaa ", -" ## ", -" ## ", -" ## ", -" ## ", -" ## ", -" ## ", -" ## ", -" ##aaaaaaaaaaaaaaaaaa ", -" ## ", -" ## ", -" ## ", -" ## ", -" ## ", -" ## ", -" ## ", -" ##aaaaaaaaaaaaaaaaaa ", -" ## ", -" ## ", -" ## ", -" ## ", -" ## "}; - -#endif // GRAPHICS_H diff --git a/src/qconfig/main.cpp b/src/qconfig/main.cpp deleted file mode 100644 index a9ff84869..000000000 --- a/src/qconfig/main.cpp +++ /dev/null @@ -1,545 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ - -#include "graphics.h" -#include "feature.h" -#include "featuretreemodel.h" - -#include <QtCore/QLibraryInfo> -#include <QtCore/QSettings> -#include <QtWidgets/QTextBrowser> -#include <QtWidgets/QTreeView> -#include <QtWidgets/QMainWindow> -#include <QtWidgets/QSplitter> -#include <QtWidgets/QMenu> -#include <QtWidgets/QMenuBar> -#include <QtWidgets/QAction> -#include <QtWidgets/QToolBar> -#include <QtWidgets/QToolButton> -#include <QtWidgets/QMessageBox> -#include <QtWidgets/QFileDialog> -#include <QtWidgets/QStatusBar> -#include <QtWidgets/QApplication> - -QT_BEGIN_NAMESPACE - -static QString defaultPath; - -class FeatureTextBrowser : public QTextBrowser { - Q_OBJECT -public: - FeatureTextBrowser(QWidget *parent) : QTextBrowser(parent) { - QString docRoot; - docRoot = QLibraryInfo::location(QLibraryInfo::DocumentationPath) - + "/html"; - setSearchPaths(searchPaths() << docRoot); - } - -signals: - void featureClicked(const QString &feature); - -public slots: - void setSource(const QUrl &url) - { - if (url.scheme() == "feature") - emit featureClicked(url.authority()); - else - QTextBrowser::setSource(url); - } -}; - -class Main : public QMainWindow { - Q_OBJECT -public: - Main(); - ~Main(); - void loadFeatures(const QString& filename); - void loadConfig(const QString& filename); - -public slots: - void modelChanged(); - void showInfo(const QModelIndex &index); - void showInfo(const QString &feature); - void openConfig(); - void saveConfig(); - void expandView(); - void collapseView(); - void about(); - void aboutQt(); - void quit(); - void clear(); - void enableAll(); - void disableAll(); - -private: - QTextBrowser *textBrowser; - QTreeView *featureTree; - FeatureTreeModel *featureModel; - - void init(); - void updateStatus(int numFeatures = -1); - void completelyExpandIndex(const QModelIndex &parent); -}; - -template<typename Func> -void foreachIndex_helper(const QModelIndex &parent, Func func) -{ - const QAbstractItemModel *model = parent.model(); - const int rows = model->rowCount(parent); - for (int i = 0; i < rows; ++i) { - const QModelIndex child = model->index(i, 0, parent); - func(child); - foreachIndex_helper(child, func); - } -} - -template<typename Func> -void foreachIndex(const QAbstractItemModel *model, Func func) -{ - const int rows = model->rowCount(QModelIndex()); - for (int i = 0; i < rows; ++i) { - const QModelIndex child = model->index(i, 0, QModelIndex()); - func(child); - foreachIndex_helper(child, func); - } -} - -struct CheckStateSetter { - - CheckStateSetter(Qt::CheckState state, QAbstractItemModel *m) - : checkState(state), model(m) {} - - void operator()(const QModelIndex &index) { - model->setData(index, checkState, Qt::CheckStateRole); - } - - Qt::CheckState checkState; - QAbstractItemModel *model; -}; - -void Main::disableAll() -{ - QAbstractItemModel *model = featureTree->model(); - foreachIndex(model, CheckStateSetter(Qt::Unchecked, model)); -} - -void Main::enableAll() -{ - QAbstractItemModel *model = featureTree->model(); - foreachIndex(model, CheckStateSetter(Qt::Checked, model)); -} - -Main::Main() -{ - setWindowIcon(QIcon(QPixmap(logo_xpm))); - - QSplitter *splitter = new QSplitter(this); - - featureModel = new FeatureTreeModel(this); - featureTree = new QTreeView(splitter); - splitter->addWidget(featureTree); - featureTree->setRootIsDecorated(true); - featureTree->setModel(featureModel); - featureTree->show(); - - textBrowser = new FeatureTextBrowser(splitter); - textBrowser->setFrameStyle(QFrame::WinPanel|QFrame::Sunken); - splitter->addWidget(textBrowser); - textBrowser->show(); - - connect(textBrowser, SIGNAL(featureClicked(QString)), - this, SLOT(showInfo(QString))); - connect(featureTree, SIGNAL(activated(QModelIndex)), - this, SLOT(showInfo(QModelIndex))); - connect(featureModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), - this, SLOT(modelChanged())); - connect(featureTree, SIGNAL(clicked(QModelIndex)), - this, SLOT(showInfo(QModelIndex))); - - setCentralWidget(splitter); - - QMenu *file = menuBar()->addMenu("&File"); - file->addAction("&Open...", this, SLOT(openConfig()), - Qt::CTRL + Qt::Key_O); - file->addAction("&Save As...", this, SLOT(saveConfig()), - Qt::CTRL + Qt::Key_S); - file->addSeparator(); - file->addAction("&Reset", this, SLOT(clear())); - file->addSeparator(); - file->addAction("E&xit", this, SLOT(quit()), Qt::CTRL + Qt::Key_Q); - - QMenu *edit = menuBar()->addMenu("&Tools"); - edit->addAction("&Enable all features", this, SLOT(enableAll())); - edit->addAction("&Disable all features", this, SLOT(disableAll())); - - menuBar()->addSeparator(); - - QMenu *help = menuBar()->addMenu("&Help"); - help->addAction("&About", this, SLOT(about())); - help->addAction("About &Qt", this, SLOT(aboutQt())); - - QToolBar *tb = new QToolBar("Expand/Collapse features"); - QToolButton *button; - - button = new QToolButton(tb); - button->setIcon(QIcon(QPixmap(collapsed_xpm))); - button->setText("Collapse"); - button->setToolTip("Collapse"); - connect(button, SIGNAL(clicked()), this, SLOT(collapseView())); - tb->addWidget(button); - - button = new QToolButton(tb); - button->setIcon(QIcon(QPixmap(expanded_xpm))); - button->setText("Expand"); - button->setToolTip("Expand"); - connect(button, SIGNAL(clicked()), this, SLOT(expandView())); - tb->addWidget(button); - addToolBar(tb); - - init(); -} - -Main::~Main() -{ - delete textBrowser; - delete featureModel; - delete featureTree; -} - -void Main::clear() -{ - QSettings settings; - settings.clear(); - featureModel->clear(); - featureTree->reset(); - init(); -} - -void Main::quit() -{ - if (isWindowModified()) { - int button = QMessageBox::question(this, "Quit Program", - "You have unsaved changes.\n" - "Do you want to quit anyway?", - QMessageBox::Yes, - QMessageBox::No); - if (static_cast<QMessageBox::Button>(button) != QMessageBox::Yes) - return; - } - QApplication::instance()->quit(); -} - -/* - Recursively expand expand \a parent and all of its children. -*/ -void Main::completelyExpandIndex(const QModelIndex &parent) -{ - featureTree->setExpanded(parent, true); - - const QAbstractItemModel *model = featureTree->model(); - const int rows = model->rowCount(parent); - for (int i = 0; i < rows; ++i) - completelyExpandIndex(model->index(i, 0, parent)); -} - -void Main::expandView() -{ - completelyExpandIndex(QModelIndex()); -} - -void Main::collapseView() -{ - const QAbstractItemModel *model = featureTree->model(); - const int rows = model->rowCount(QModelIndex()); - for (int i = 0; i < rows; ++i) { - QModelIndex index = model->index(i, 0, QModelIndex()); - featureTree->setExpanded(index, false); - } -} - -void Main::updateStatus(int numFeatures) -{ - QSettings settings; - QString featureFile = settings.value("featureFile").toString(); - QString configFile = settings.value("lastConfig").toString(); - QString message("Using features from %1"); - - if (numFeatures >= 0) { - QString s("%1 features loaded from %2"); - statusBar()->showMessage(s.arg(numFeatures).arg(featureFile)); - } - QString appName = QApplication::applicationName(); - if (configFile.isEmpty()) - configFile = "New File"; - setWindowTitle(appName + " - " + configFile + "[*]"); -} - -void Main::modelChanged() -{ - setWindowModified(true); -} - -void Main::init() -{ - QSettings settings; - QString features = settings.value("featureFile").toString(); - - if (features.isEmpty() || !QFileInfo(features).isFile()) { - features = QFileDialog::getOpenFileName(this, - "Open a feature file", - defaultPath, - "Qt Features (qfeatures.txt)"); - } - settings.setValue("featureFile", features); - loadFeatures(features); - - expandView(); - collapseView(); - - QString confFile = settings.value("lastConfig").toString(); - if (confFile.isEmpty()) - return; - loadConfig(confFile); -} - -void Main::openConfig() -{ - QSettings settings; - QString configDir; - - QString prevFile = settings.value("lastConfig").toString(); - if (!prevFile.isEmpty()) - configDir = QFileInfo(prevFile).path(); - - if (configDir.isEmpty()) - configDir = defaultPath; - - QString configFile; - configFile = QFileDialog::getOpenFileName(this, - "Open a configuration file", - configDir, - "Header files (*.h)"); - enableAll(); - if (!configFile.isEmpty()) - loadConfig(configFile); - settings.setValue("lastConfig", QFileInfo(configFile).absoluteFilePath()); -} - -void Main::saveConfig() -{ - QSettings settings; - QString configDir; - - QString prevFile = settings.value("lastConfig").toString(); - if (!prevFile.isEmpty()) - configDir = QFileInfo(prevFile).path(); - - if (configDir.isEmpty()) - configDir = defaultPath; - - QString configFile; - configFile = QFileDialog::getSaveFileName(this, - "Save configuration file", - configDir, - "Header files (*.h)"); - if (configFile.isEmpty()) - return; - - QFile file(configFile); - if (!file.open(QIODevice::WriteOnly)) { - QMessageBox::warning(this,"Warning", - "Cannot write to file " + configFile); - return; - } - - QTextStream stream(&file); - FeatureTreeModel *model; - model = static_cast<FeatureTreeModel*>(featureTree->model()); - model->writeConfig(stream); - - settings.setValue("lastConfig", QFileInfo(configFile).absoluteFilePath()); - setWindowModified(false); - updateStatus(); -} - -void Main::loadConfig(const QString &filename) -{ - if (!QFileInfo(filename).isFile()) - return; - - QFile file(filename); - if (!file.open(QIODevice::ReadOnly)) { - QMessageBox::warning(this,"Warning", "Cannot open file " + filename); - return; - } - - QTextStream stream(&file); - FeatureTreeModel *model; - model = static_cast<FeatureTreeModel*>(featureTree->model()); - model->readConfig(stream); - - QSettings settings; - settings.setValue("lastConfig", QFileInfo(filename).absoluteFilePath()); - setWindowModified(false); - updateStatus(); -} - -void Main::loadFeatures(const QString &filename) -{ - Feature::clear(); - - QFile file(filename); - if (!file.open(QIODevice::ReadOnly)) { - QMessageBox::warning(this,"Warning", "Cannot open file " + filename); - return; - } - - Feature *feature = 0; - int numFeatures = 0; - updateStatus(numFeatures); - QTextStream s(&file); - for (QString line = s.readLine(); !s.atEnd(); line = s.readLine()) { - line = line.simplified(); - if (line.isEmpty()) - continue; - if (line.startsWith('#')) - continue; - - int colon = line.indexOf(':'); - if (colon < 0) { // assume description - QString description = feature->description().simplified(); - description += " " + line; - feature->setDescription(description); - continue; - } - - QString tag = line.left(colon); - QString value = line.mid(colon+1).simplified(); - if (tag == "Feature") { - if (feature) - featureModel->addFeature(feature); - feature = Feature::getInstance(value); - updateStatus(++numFeatures); - } else if (tag == "Requires") { - Q_ASSERT(feature); - feature->setDependencies(value.split(' ', QString::SkipEmptyParts)); - } else if (tag == "Name") { - Q_ASSERT(feature); - feature->setTitle(value); - } else if (tag == "Section") { - Q_ASSERT(feature); - feature->setSection(value); - } else if (tag == "SeeAlso") { - Q_ASSERT(feature); - feature->setRelations(value.split(' ', QString::SkipEmptyParts)); - } else if (tag == "Description") { - Q_ASSERT(feature); - feature->setDescription(value); - } - } - if (feature) - featureModel->addFeature(feature); - - featureTree->resizeColumnToContents(0); - - QSettings settings; - settings.setValue("featureFile", QFileInfo(filename).absoluteFilePath()); - - updateStatus(); -} - -void Main::showInfo(const QModelIndex &index) -{ - FeatureTreeModel *model; - model = static_cast<FeatureTreeModel*>(featureTree->model()); - - if (const Feature *feature = model->getFeature(index)) - textBrowser->setHtml(feature->toHtml()); - - // Ensure index is visible - QModelIndex parent = model->parent(index); - while (parent.isValid()) { - featureTree->setExpanded(parent, true); - parent = model->parent(parent); - } - - featureTree->scrollTo(index); - featureTree->setCurrentIndex(index); -} - -void Main::showInfo(const QString &feature) -{ - const Feature *f = Feature::getInstance(feature); - FeatureTreeModel *model; - model = static_cast<FeatureTreeModel*>(featureTree->model()); - showInfo(model->index(f)); -} - -void Main::about() -{ - QMessageBox::about(this, "About qconfig", - "<p><b><font size=\"+2\">Qtopia Core build configuration</font></b></p>" - "<p></p>" - "<p>Version 2.0</p>" - "<p>Copyright (C) 2016 The Qt Company Ltd.</p>" - "<p></p>" - ); -} - -void Main::aboutQt() -{ - QMessageBox::aboutQt( this, tr("qconfig") ); -} - -QT_END_NAMESPACE - -int main(int argc, char** argv) -{ - QT_USE_NAMESPACE - QApplication app(argc,argv); - app.setOrganizationDomain("qt-project.org"); - app.setOrganizationName("QtProject"); - app.setApplicationName("QConfig"); - Main m; - - defaultPath = QLibraryInfo::location(QLibraryInfo::PrefixPath) - + "/src/corelib/global"; - - for (int i = 1; i < argc; ++i) { - QString arg = argv[i]; - if (arg == "-f" && i+1 < argc) - m.loadFeatures(argv[++i]); - else if (arg == "-c" && i+1 < argc) - m.loadConfig(argv[++i]); - } - m.resize(m.sizeHint() + QSize(500,300)); - m.show(); - return app.exec(); -} - -#include "main.moc" diff --git a/src/qconfig/qconfig.pro b/src/qconfig/qconfig.pro deleted file mode 100644 index aa64dde32..000000000 --- a/src/qconfig/qconfig.pro +++ /dev/null @@ -1,6 +0,0 @@ -QT += widgets - -HEADERS = feature.h featuretreemodel.h graphics.h -SOURCES = main.cpp feature.cpp featuretreemodel.cpp - -load(qt_app) diff --git a/src/qdoc/config.cpp b/src/qdoc/config.cpp index 8c8403878..46d7c5bf1 100644 --- a/src/qdoc/config.cpp +++ b/src/qdoc/config.cpp @@ -51,6 +51,7 @@ QString ConfigStrings::CODEINDENT = QStringLiteral("codeindent"); QString ConfigStrings::CODEPREFIX = QStringLiteral("codeprefix"); QString ConfigStrings::CODESUFFIX = QStringLiteral("codesuffix"); QString ConfigStrings::CPPCLASSESPAGE = QStringLiteral("cppclassespage"); +QString ConfigStrings::CPPCLASSESTITLE = QStringLiteral("cppclassestitle"); QString ConfigStrings::DEFINES = QStringLiteral("defines"); QString ConfigStrings::DEPENDS = QStringLiteral("depends"); QString ConfigStrings::DESCRIPTION = QStringLiteral("description"); @@ -117,6 +118,7 @@ QString ConfigStrings::FILEEXTENSIONS = QStringLiteral("fileextensions"); QString ConfigStrings::IMAGEEXTENSIONS = QStringLiteral("imageextensions"); QString ConfigStrings::QMLONLY = QStringLiteral("qmlonly"); QString ConfigStrings::QMLTYPESPAGE = QStringLiteral("qmltypespage"); +QString ConfigStrings::QMLTYPESTITLE = QStringLiteral("qmltypestitle"); QString ConfigStrings::WRITEQAPAGES = QStringLiteral("writeqapages"); /*! @@ -385,12 +387,15 @@ QSet<QString> Config::getOutputFormats() const Then it looks up the configuration variable \a var in the string map and returns the string that \a var maps to. + + If \a var is not contained in the location map it returns + \a defaultString. */ -QString Config::getString(const QString& var) const +QString Config::getString(const QString& var, const QString& defaultString) const { QList<ConfigVar> configVars = configVars_.values(var); - QString value; if (!configVars.empty()) { + QString value; int i = configVars.size() - 1; while (i >= 0) { const ConfigVar& cv = configVars[i]; @@ -407,8 +412,9 @@ QString Config::getString(const QString& var) const } --i; } + return value; } - return value; + return defaultString; } /*! diff --git a/src/qdoc/config.h b/src/qdoc/config.h index f51e23e58..298cd3f63 100644 --- a/src/qdoc/config.h +++ b/src/qdoc/config.h @@ -87,7 +87,7 @@ public: int getInt(const QString& var) const; QString getOutputDir() const; QSet<QString> getOutputFormats() const; - QString getString(const QString& var) const; + QString getString(const QString& var, const QString& defaultString = QString()) const; QSet<QString> getStringSet(const QString& var) const; QStringList getStringList(const QString& var) const; QStringList getCanonicalPathList(const QString& var, bool validate = false) const; @@ -164,6 +164,7 @@ struct ConfigStrings static QString CODEPREFIX; static QString CODESUFFIX; static QString CPPCLASSESPAGE; + static QString CPPCLASSESTITLE; static QString DEFINES; static QString DEPENDS; static QString DESCRIPTION; @@ -230,6 +231,7 @@ struct ConfigStrings static QString IMAGEEXTENSIONS; static QString QMLONLY; static QString QMLTYPESPAGE; + static QString QMLTYPESTITLE; static QString WRITEQAPAGES; }; @@ -242,6 +244,7 @@ struct ConfigStrings #define CONFIG_CODEPREFIX ConfigStrings::CODEPREFIX #define CONFIG_CODESUFFIX ConfigStrings::CODESUFFIX #define CONFIG_CPPCLASSESPAGE ConfigStrings::CPPCLASSESPAGE +#define CONFIG_CPPCLASSESTITLE ConfigStrings::CPPCLASSESTITLE #define CONFIG_DEFINES ConfigStrings::DEFINES #define CONFIG_DEPENDS ConfigStrings::DEPENDS #define CONFIG_DESCRIPTION ConfigStrings::DESCRIPTION @@ -308,6 +311,7 @@ struct ConfigStrings #define CONFIG_IMAGEEXTENSIONS ConfigStrings::IMAGEEXTENSIONS #define CONFIG_QMLONLY ConfigStrings::QMLONLY #define CONFIG_QMLTYPESPAGE ConfigStrings::QMLTYPESPAGE +#define CONFIG_QMLTYPESTITLE ConfigStrings::QMLTYPESTITLE #define CONFIG_WRITEQAPAGES ConfigStrings::WRITEQAPAGES QT_END_NAMESPACE diff --git a/src/qdoc/cppcodeparser.cpp b/src/qdoc/cppcodeparser.cpp index 57cd1e917..c7d1e3507 100644 --- a/src/qdoc/cppcodeparser.cpp +++ b/src/qdoc/cppcodeparser.cpp @@ -522,6 +522,8 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc, ptype = Node::FAQPage; else if (t == "ditamap") ptype = Node::DitaMapPage; + else if (t == "attribution") + ptype = Node::AttributionPage; } DocumentNode* dn = 0; if (ptype == Node::DitaMapPage) diff --git a/src/qdoc/doc/qdoc-manual-markupcmds.qdoc b/src/qdoc/doc/qdoc-manual-markupcmds.qdoc index e4f8f048c..4f7cbf735 100644 --- a/src/qdoc/doc/qdoc-manual-markupcmds.qdoc +++ b/src/qdoc/doc/qdoc-manual-markupcmds.qdoc @@ -3413,6 +3413,18 @@ navigation.landingpage configuration variable. The \e landingpage variable is used as a title for a header that precedes each table. + \section2 \c annotatedattributions + + The \c annotatedattributions argument provides a complete list of all + attributions as a set of tables containing the titles of all the + attributions, and a description of each attribution. Each title is a + link to the attribution's page. + + A separate table for each module (that has attributions) + is generated, provided that the module has defined a + navigation.landingpage configuration variable. The \e landingpage + variable is used as a title for a header that precedes each table. + \target list example \section2 \c {classes <prefix>} @@ -3562,6 +3574,11 @@ * / \endcode + \section2 \c attributions + + The \c attributions argument is used to tell QDoc to generate a list + of attributions in the documentation. + \section2 \c related The \c related argument is used in combination with the \l diff --git a/src/qdoc/generator.cpp b/src/qdoc/generator.cpp index b91626460..69d0dbb4b 100644 --- a/src/qdoc/generator.cpp +++ b/src/qdoc/generator.cpp @@ -1086,10 +1086,7 @@ void Generator::generateInherits(const ClassNode *classe, CodeMarker *marker) index = 0; while (r != classe->baseClasses().constEnd()) { if ((*r).node_) { - text << Atom(Atom::LinkNode, CodeMarker::stringForNode((*r).node_)) - << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) - << Atom(Atom::String, (*r).signature_) - << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); + appendFullName(text, (*r).node_, classe); if ((*r).access_ == Node::Protected) { text << " (protected)"; diff --git a/src/qdoc/htmlgenerator.cpp b/src/qdoc/htmlgenerator.cpp index 690ba9527..9e318dee3 100644 --- a/src/qdoc/htmlgenerator.cpp +++ b/src/qdoc/htmlgenerator.cpp @@ -256,10 +256,20 @@ void HtmlGenerator::initializeGenerator(const Config &config) + Config::dot + CONFIG_CPPCLASSESPAGE); + cppclassestitle = config.getString(CONFIG_NAVIGATION + + Config::dot + + CONFIG_CPPCLASSESTITLE, + QLatin1String("C++ Classes")); + qmltypespage = config.getString(CONFIG_NAVIGATION + Config::dot + CONFIG_QMLTYPESPAGE); + qmltypestitle = config.getString(CONFIG_NAVIGATION + + Config::dot + + CONFIG_QMLTYPESTITLE, + QLatin1String("QML Types")); + buildversion = config.getString(CONFIG_BUILDVERSION); } @@ -674,6 +684,9 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark else if (atom->string() == QLatin1String("annotatedexamples")) { generateAnnotatedLists(relative, marker, qdb_->getExamples()); } + else if (atom->string() == QLatin1String("annotatedattributions")) { + generateAnnotatedLists(relative, marker, qdb_->getAttributions()); + } else if (atom->string() == QLatin1String("classes")) { generateCompactList(Generic, relative, qdb_->getCppClasses(), true, QStringLiteral("")); } @@ -694,6 +707,8 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark genus = Node::QML; else if (atom->string().startsWith(QLatin1String("js"))) genus = Node::JS; + else if (atom->string().startsWith(QLatin1String("groups"))) + genus = Node::DOC; QDocDatabase* qdb = QDocDatabase::qdocDB(); const CollectionNode* cn = qdb->getCollectionNode(moduleName, genus); if (cn) { @@ -726,6 +741,9 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark else if (atom->string() == QLatin1String("functionindex")) { generateFunctionIndex(relative); } + else if (atom->string() == QLatin1String("attributions")) { + generateAnnotatedList(relative, marker, qdb_->getAttributions()); + } else if (atom->string() == QLatin1String("legalese")) { generateLegaleseList(relative, marker); } @@ -1899,11 +1917,11 @@ void HtmlGenerator::generateNavigationBar(const QString &title, << Atom(itemRight); if (node->isClass()) { - if (!cppclassespage.isEmpty()) + if (!cppclassespage.isEmpty() && !cppclassestitle.isEmpty()) navigationbar << Atom(itemLeft) << Atom(Atom::NavLink, cppclassespage) << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) - << Atom(Atom::String, QLatin1String("C++ Classes")) + << Atom(Atom::String, cppclassestitle) << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) << Atom(itemRight); @@ -1914,11 +1932,11 @@ void HtmlGenerator::generateNavigationBar(const QString &title, } else if (node->isQmlType() || node->isQmlBasicType() || node->isJsType() || node->isJsBasicType()) { - if (!qmltypespage.isEmpty()) + if (!qmltypespage.isEmpty() && !qmltypestitle.isEmpty()) navigationbar << Atom(itemLeft) << Atom(Atom::NavLink, qmltypespage) << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) - << Atom(Atom::String, QLatin1String("QML Types")) + << Atom(Atom::String, qmltypestitle) << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) << Atom(itemRight) << Atom(itemLeft) @@ -2235,10 +2253,7 @@ void HtmlGenerator::generateRequisites(Aggregate *inner, CodeMarker *marker) index = 0; while (r != classe->baseClasses().constEnd()) { if ((*r).node_) { - text << Atom(Atom::LinkNode, CodeMarker::stringForNode((*r).node_)) - << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) - << Atom(Atom::String, (*r).signature_) - << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); + appendFullName(text, (*r).node_, classe); if ((*r).access_ == Node::Protected) { text << " (protected)"; diff --git a/src/qdoc/htmlgenerator.h b/src/qdoc/htmlgenerator.h index 0e30a08da..b4483e33f 100644 --- a/src/qdoc/htmlgenerator.h +++ b/src/qdoc/htmlgenerator.h @@ -263,7 +263,9 @@ private: QString homepage; QString landingpage; QString cppclassespage; + QString cppclassestitle; QString qmltypespage; + QString qmltypestitle; QString buildversion; QString qflagsHref_; int tocDepth; diff --git a/src/qdoc/node.cpp b/src/qdoc/node.cpp index d530c180b..7bec46843 100644 --- a/src/qdoc/node.cpp +++ b/src/qdoc/node.cpp @@ -379,6 +379,8 @@ QString Node::pageTypeString() const QString Node::pageTypeString(unsigned char t) { switch ((PageType)t) { + case Node::AttributionPage: + return "attribution"; case Node::ApiPage: return "api"; case Node::ArticlePage: @@ -1266,8 +1268,17 @@ bool Aggregate::isSameSignature(const FunctionNode *f1, const FunctionNode *f2) ### hack for C++ to handle superfluous "Foo::" prefixes gracefully */ - if (t1 != t2 && t1 != (f2->parent()->name() + "::" + t2)) - return false; + if (t1 != t2 && t1 != (f2->parent()->name() + "::" + t2)) { + // Accept a difference in the template parametters of the type if one + // is omited (eg. "QAtomicInteger" == "QAtomicInteger<T>") + auto ltLoc = t1.indexOf('<'); + auto gtLoc = t1.indexOf('>', ltLoc); + if (ltLoc < 0 || gtLoc < ltLoc) + return false; + t1.remove(ltLoc, gtLoc - ltLoc + 1); + if (t1 != t2) + return false; + } } ++p1; ++p2; diff --git a/src/qdoc/node.h b/src/qdoc/node.h index eeb16e1b4..efe8c4896 100644 --- a/src/qdoc/node.h +++ b/src/qdoc/node.h @@ -92,6 +92,7 @@ public: enum DocSubtype { NoSubtype, + Attribution, Example, HeaderFile, File, @@ -133,6 +134,7 @@ public: enum PageType { NoPageType, + AttributionPage, ApiPage, ArticlePage, ExamplePage, diff --git a/src/qdoc/qdocdatabase.cpp b/src/qdoc/qdocdatabase.cpp index 3b47d6b6e..c6650e830 100644 --- a/src/qdoc/qdocdatabase.cpp +++ b/src/qdoc/qdocdatabase.cpp @@ -842,6 +842,7 @@ void QDocDatabase::processForest() findAllObsoleteThings(t->root()); findAllLegaleseTexts(t->root()); findAllSince(t->root()); + findAllAttributions(t->root()); t->setTreeHasBeenAnalyzed(); t = forest_.nextTree(); } @@ -955,6 +956,18 @@ NodeMultiMap& QDocDatabase::getExamples() } /*! + Construct the data structures for attributions, if they + have not already been constructed. Returns a reference to + the multimap of attribution nodes. + */ +NodeMultiMap& QDocDatabase::getAttributions() +{ + if (attributions_.isEmpty()) + processForest(&QDocDatabase::findAllAttributions); + return attributions_; +} + +/*! Construct the data structures for obsolete things, if they have not already been constructed. Returns a reference to the map of obsolete C++ clases. @@ -1055,6 +1068,25 @@ void QDocDatabase::findAllFunctions(Aggregate* node) } /*! + Finds all the attribution pages and collects them per module + */ +void QDocDatabase::findAllAttributions(Aggregate* node) +{ + NodeList::ConstIterator c = node->childNodes().constBegin(); + while (c != node->childNodes().constEnd()) { + if ((*c)->access() != Node::Private) { + if ((*c)->docSubtype() == Node::Page + && (*c)->pageType() == Node::AttributionPage) { + attributions_.insertMulti((*c)->tree()->indexTitle(), *c); + } else if ((*c)->isAggregate()) { + findAllAttributions(static_cast<Aggregate*>(*c)); + } + } + ++c; + } +} + +/*! Finds all the nodes containing legalese text and puts them in a map. */ diff --git a/src/qdoc/qdocdatabase.h b/src/qdoc/qdocdatabase.h index afb78a95f..0af094878 100644 --- a/src/qdoc/qdocdatabase.h +++ b/src/qdoc/qdocdatabase.h @@ -266,6 +266,7 @@ class QDocDatabase private: void findAllClasses(Aggregate *node); void findAllFunctions(Aggregate *node); + void findAllAttributions(Aggregate *node); void findAllLegaleseTexts(Aggregate *node); void findAllNamespaces(Aggregate *node); void findAllObsoleteThings(Aggregate* node); @@ -284,6 +285,7 @@ class QDocDatabase NodeMultiMap& getQmlBasicTypes(); NodeMultiMap& getQmlTypes(); NodeMultiMap& getExamples(); + NodeMultiMap& getAttributions(); NodeMapMap& getFunctionIndex(); TextToNodeMap& getLegaleseTexts(); const NodeMap& getClassMap(const QString& key); @@ -453,6 +455,7 @@ class QDocDatabase NodeMultiMap qmlBasicTypes_; NodeMultiMap qmlTypes_; NodeMultiMap examples_; + NodeMultiMap attributions_; NodeMapMap newClassMaps_; NodeMapMap newQmlTypeMaps_; NodeMultiMapMap newSinceMaps_; diff --git a/src/qdoc/qdocindexfiles.cpp b/src/qdoc/qdocindexfiles.cpp index 888d451c7..03f9c9811 100644 --- a/src/qdoc/qdocindexfiles.cpp +++ b/src/qdoc/qdocindexfiles.cpp @@ -398,7 +398,11 @@ void QDocIndexFiles::readIndexSection(QXmlStreamReader& reader, Node::DocSubtype subtype; Node::PageType ptype = Node::NoPageType; QString attr = attributes.value(QLatin1String("subtype")).toString(); - if (attr == QLatin1String("example")) { + if (attr == QLatin1String("attribution")) { + subtype = Node::Page; + ptype = Node::AttributionPage; + } + else if (attr == QLatin1String("example")) { subtype = Node::Example; ptype = Node::ExamplePage; } @@ -1070,7 +1074,11 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer, writer.writeAttribute("subtype", "file"); break; case Node::Page: - writer.writeAttribute("subtype", "page"); + if (docNode->pageType() == Node::AttributionPage) + writer.writeAttribute("subtype", "attribution"); + else + writer.writeAttribute("subtype", "page"); + writeModuleName = true; break; case Node::ExternalPage: diff --git a/src/qtattributionsscanner/jsongenerator.cpp b/src/qtattributionsscanner/jsongenerator.cpp new file mode 100644 index 000000000..580fddf57 --- /dev/null +++ b/src/qtattributionsscanner/jsongenerator.cpp @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $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$ +** +****************************************************************************/ + +#include "jsongenerator.h" + +#include <QtCore/qjsonarray.h> +#include <QtCore/qjsondocument.h> +#include <QtCore/qjsonobject.h> + +#include <iostream> + +namespace JsonGenerator { + +static QJsonObject generate(Package package) +{ + QJsonObject obj; + + obj.insert(QStringLiteral("Id"), package.id); + obj.insert(QStringLiteral("Path"), package.path); + obj.insert(QStringLiteral("Files"), package.files.join(QLatin1Char(' '))); + obj.insert(QStringLiteral("QDocModule"), package.qdocModule); + obj.insert(QStringLiteral("Name"), package.name); + obj.insert(QStringLiteral("QtUsage"), package.qtUsage); + + obj.insert(QStringLiteral("Description"), package.description); + obj.insert(QStringLiteral("Homepage"), package.homepage); + obj.insert(QStringLiteral("Version"), package.version); + obj.insert(QStringLiteral("DownloadLocation"), package.downloadLocation); + + obj.insert(QStringLiteral("License"), package.license); + obj.insert(QStringLiteral("LicenseId"), package.licenseId); + obj.insert(QStringLiteral("LicenseFile"), package.licenseFile); + + obj.insert(QStringLiteral("Copyright"), package.copyright); + + return obj; +} + +void generate(QTextStream &out, const QVector<Package> &packages, LogLevel logLevel) +{ + if (logLevel == VerboseLog) + std::cerr << qPrintable(tr("Generating json...\n")); + + QJsonDocument document; + QJsonArray array; + foreach (const Package &package, packages) + array.append(generate(package)); + document.setArray(array); + + out << document.toJson(); +} + +} // namespace JsonGenerator diff --git a/src/qtattributionsscanner/jsongenerator.h b/src/qtattributionsscanner/jsongenerator.h new file mode 100644 index 000000000..a4b6f11e2 --- /dev/null +++ b/src/qtattributionsscanner/jsongenerator.h @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $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$ +** +****************************************************************************/ + +#ifndef JSONGENERATOR +#define JSONGENERATOR + +#include "logging.h" +#include "package.h" + +#include <QtCore/qtextstream.h> +#include <QtCore/qvector.h> + +namespace JsonGenerator { + +void generate(QTextStream &out, const QVector<Package> &packages, LogLevel logLevel); + +} // namespace JsonGenerator + +#endif // JSONGENERATOR diff --git a/src/qtattributionsscanner/logging.h b/src/qtattributionsscanner/logging.h new file mode 100644 index 000000000..6810da6ca --- /dev/null +++ b/src/qtattributionsscanner/logging.h @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $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$ +** +****************************************************************************/ + +#ifndef LOGGING_H +#define LOGGING_H + +#include <QtCore/qcoreapplication.h> + +enum LogLevel { + VerboseLog, + NormalLog, + SilentLog +}; + +static QString tr(const char *key) { + return QCoreApplication::translate("qtattributionsscanner", key); +} + +#endif // LOGGING_H diff --git a/src/qtattributionsscanner/main.cpp b/src/qtattributionsscanner/main.cpp new file mode 100644 index 000000000..cd9bc1fed --- /dev/null +++ b/src/qtattributionsscanner/main.cpp @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $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$ +** +****************************************************************************/ + +#include "jsongenerator.h" +#include "logging.h" +#include "packagefilter.h" +#include "qdocgenerator.h" +#include "scanner.h" + +#include <QtCore/qcommandlineparser.h> +#include <QtCore/qcoreapplication.h> +#include <QtCore/qdir.h> +#include <QtCore/qfile.h> + +#include <iostream> + + +int main(int argc, char *argv[]) +{ + QCoreApplication a(argc, argv); + a.setApplicationName(QStringLiteral("Qt Attributions Scanner")); + a.setApplicationVersion(QStringLiteral("1.0")); + + QCommandLineParser parser; + parser.setApplicationDescription(tr("Searches and processes qt_attribution.json files in Qt sources.")); + parser.addPositionalArgument(QStringLiteral("directory"), + tr("The directory to scan recursively.")); + parser.addHelpOption(); + parser.addVersionOption(); + + QCommandLineOption generatorOption(QStringLiteral("output-format"), + tr("Output format (\"qdoc\", \"json\")."), + QStringLiteral("generator"), + QStringLiteral("qdoc")); + QCommandLineOption filterOption(QStringLiteral("filter"), + tr("Filter packages according to <filter> (e.g. QDocModule=qtcore)"), + QStringLiteral("expression")); + QCommandLineOption outputOption({ QStringLiteral("o"), QStringLiteral("output") }, + tr("Write generated data to <file>."), + QStringLiteral("file")); + QCommandLineOption verboseOption(QStringLiteral("verbose"), + tr("Verbose output.")); + QCommandLineOption silentOption({ QStringLiteral("s"), QStringLiteral("silent") }, + tr("Minimal output.")); + + parser.addOption(generatorOption); + parser.addOption(filterOption); + parser.addOption(outputOption); + parser.addOption(verboseOption); + parser.addOption(silentOption); + + parser.process(a.arguments()); + + LogLevel logLevel = NormalLog; + if (parser.isSet(verboseOption) && parser.isSet(silentOption)) { + std::cerr << qPrintable(tr("--verbose and --silent cannot be set simultaneously.")) << std::endl; + parser.showHelp(1); + } + + if (parser.isSet(verboseOption)) + logLevel = VerboseLog; + else if (parser.isSet(silentOption)) + logLevel = SilentLog; + + if (parser.positionalArguments().size() != 1) + parser.showHelp(2); + + const QString directory = parser.positionalArguments().last(); + + if (logLevel == VerboseLog) + std::cerr << qPrintable(tr("Recursively scanning %1 for qt_attribution.json files...").arg( + QDir::toNativeSeparators(directory))) << std::endl; + + QVector<Package> packages = Scanner::scanDirectory(directory, logLevel); + + if (parser.isSet(filterOption)) { + PackageFilter filter(parser.value(filterOption)); + if (filter.type == PackageFilter::InvalidFilter) + return 4; + packages.erase(std::remove_if(packages.begin(), packages.end(), + [&filter](const Package &p) { return !filter(p); }), + packages.end()); + } + + if (logLevel == VerboseLog) + std::cerr << qPrintable(tr("%1 packages found.").arg(packages.size())) << std::endl; + + QTextStream out(stdout); + QFile outFile(parser.value(outputOption)); + if (!outFile.fileName().isEmpty()) { + if (!outFile.open(QFile::WriteOnly)) { + std::cerr << qPrintable(tr("Cannot open %1 for writing.").arg( + QDir::toNativeSeparators(outFile.fileName()))) + << std::endl; + return 5; + } + out.setDevice(&outFile); + } + + QString generator = parser.value(generatorOption); + if (generator == QLatin1String("qdoc")) { + // include top level module name in printed paths + QString baseDirectory = QDir(directory).absoluteFilePath(QStringLiteral("..")); + QDocGenerator::generate(out, packages, baseDirectory, logLevel); + } else if (generator == QLatin1String("json")) { + JsonGenerator::generate(out, packages, logLevel); + } else { + std::cerr << qPrintable(tr("Unknown output-format %1.").arg(generator)) << std::endl; + return 6; + } + + if (logLevel == VerboseLog) + std::cerr << qPrintable(tr("Processing is done.")) << std::endl; + + return 0; +} diff --git a/src/qtattributionsscanner/package.h b/src/qtattributionsscanner/package.h new file mode 100644 index 000000000..31d95c9fb --- /dev/null +++ b/src/qtattributionsscanner/package.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $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$ +** +****************************************************************************/ + +#ifndef PACKAGE_H +#define PACKAGE_H + +#include <QtCore/qstring.h> +#include <QtCore/qstringlist.h> + +struct Package { + QString id; // Usually a lowercase, no-spaces version of the name. Mandatory. + QString path; // Source directory. Optional. + // Default is the directory of the qt_attribution.json file. + QStringList files; // Files in path. Optional. + QString name; // Descriptive name of the package. Will be used as the title. Mandatory. + QString qdocModule; // QDoc module where the documentation should be included. Mandatory. + QString qtUsage; // How the package is used in Qt. Any way to disable? Mandatory. + + QString description; // A short description of what the package is and is used for. Optional. + QString homepage; // Homepage of the upstream project. Optional. + QString version; // Version used from the upstream project. Optional. + QString downloadLocation; // Link to exact upstream version. Optional. + + QString license; // The license under which the package is distributed. Mandatory. + QString licenseId; // see https://spdx.org/licenses/. Optional. + QString licenseFile; // path to file containing the license text. Optional. + + QString copyright; // A list of copyright owners. Mandatory. +}; + +#endif // PACKAGE_H diff --git a/src/qtattributionsscanner/packagefilter.cpp b/src/qtattributionsscanner/packagefilter.cpp new file mode 100644 index 000000000..26fdfffc0 --- /dev/null +++ b/src/qtattributionsscanner/packagefilter.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $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$ +** +****************************************************************************/ + +#include "logging.h" +#include "packagefilter.h" +#include <iostream> + +PackageFilter::PackageFilter(const QString &expression) + : type(InvalidFilter) +{ + const QLatin1String filter("QDocModule="); + if (expression.startsWith(filter)) { + type = QDocModuleFilter; + this->expression = expression.mid(filter.size()); + } else { + std::cerr << qPrintable(tr("Invalid filter expression \"%1\"").arg(expression)) << std::endl; + std::cerr << qPrintable(tr("Currently only \"QDocModule=*\" is supported.")) << std::endl; + } +} + +bool PackageFilter::operator()(const Package &p) +{ + switch (type) { + case InvalidFilter: + return true; + case QDocModuleFilter: + return p.qdocModule == expression; + } + return false; +} diff --git a/src/designer/src/components/formeditor/qdesignerundostack.h b/src/qtattributionsscanner/packagefilter.h index 4ecf16cc8..968449445 100644 --- a/src/designer/src/components/formeditor/qdesignerundostack.h +++ b/src/qtattributionsscanner/packagefilter.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the Qt Designer of the Qt Toolkit. +** This file is part of the tools applications of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage @@ -26,53 +26,22 @@ ** ****************************************************************************/ -#ifndef QDESIGNERUNDOSTACK_H -#define QDESIGNERUNDOSTACK_H +#ifndef PACKAGEFILTER_H +#define PACKAGEFILTER_H -#include <QtCore/QObject> +#include "package.h" -QT_BEGIN_NAMESPACE -class QUndoStack; -class QUndoCommand; - -namespace qdesigner_internal { - -/* QDesignerUndoStack: A QUndoStack extended by a way of setting it to - * "dirty" indepently of commands (by modifications without commands - * such as resizing). Accomplished via bool m_fakeDirty flag. The - * lifecycle of the QUndoStack is managed by the QUndoGroup. */ -class QDesignerUndoStack : public QObject +struct PackageFilter { - Q_DISABLE_COPY(QDesignerUndoStack) - Q_OBJECT -public: - explicit QDesignerUndoStack(QObject *parent = 0); - virtual ~QDesignerUndoStack(); - - void clear(); - void push(QUndoCommand * cmd); - void beginMacro(const QString &text); - void endMacro(); - int index() const; - - const QUndoStack *qundoStack() const; - QUndoStack *qundoStack(); + PackageFilter(const QString &expression); - bool isDirty() const; + bool operator()(const Package &p); -signals: - void changed(); - -public slots: - void setDirty(bool); - -private: - QUndoStack *m_undoStack; - bool m_fakeDirty; + enum { + InvalidFilter, + QDocModuleFilter + } type; + QString expression; }; -} // namespace qdesigner_internal - -QT_END_NAMESPACE - -#endif // QDESIGNERUNDOSTACK_H +#endif // PACKAGEFILTER_H diff --git a/src/qtattributionsscanner/qdocgenerator.cpp b/src/qtattributionsscanner/qdocgenerator.cpp new file mode 100644 index 000000000..6fcccee60 --- /dev/null +++ b/src/qtattributionsscanner/qdocgenerator.cpp @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $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$ +** +****************************************************************************/ + +#include "qdocgenerator.h" + +#include <QtCore/qdir.h> + +#include <iostream> + +namespace QDocGenerator { + +// See definition of idstring and licenseid in https://spdx.org/spdx-specification-21-web-version +static bool isSpdxLicenseId(const QString &str) { + if (str.isEmpty()) + return false; + for (auto iter(str.cbegin()); iter != str.cend(); ++iter) { + const QChar c = *iter; + if (!((c >= QLatin1Char('A') && c <= QLatin1Char('Z')) + || (c >= QLatin1Char('a') && c <= QLatin1Char('z')) + || (c >= QLatin1Char('0') && c <= QLatin1Char('9')) + || (c == QLatin1Char('-')) || (c == QLatin1Char('.')))) + return false; + } + return true; +} + +static QString languageJoin(const QStringList &list) +{ + QString result; + for (int i = 0; i < list.size(); ++i) { + QString delimiter = QStringLiteral(", "); + if (i == list.size() - 1) // last item + delimiter.clear(); + else if (list.size() == 2) + delimiter = QStringLiteral(" and "); + else if (list.size() > 2 && i == list.size() - 2) + delimiter = QStringLiteral(", and "); // oxford comma + result += list[i] + delimiter; + } + + return result; +} + +static void generate(QTextStream &out, const Package &package, const QDir &baseDir, + LogLevel logLevel) +{ + out << "/*!\n\n"; + out << "\\contentspage attributions.html\n"; + out << "\\ingroup attributions-" << package.qdocModule << "\n"; + out << "\\page " << package.qdocModule << "-attribution-" << package.id << ".html attribution\n"; + out << "\\target " << package.id << "\n\n"; + out << "\\title " << package.name << "\n"; + out << "\\brief " << package.license << "\n\n"; + + if (!package.description.isEmpty()) + out << package.description << "\n\n"; + + if (!package.qtUsage.isEmpty()) + out << package.qtUsage << "\n\n"; + + QStringList sourcePaths; + if (package.files.isEmpty()) { + sourcePaths << baseDir.relativeFilePath(package.path); + } else { + const QDir packageDir(package.path); + for (const QString &filePath: package.files) { + const QString absolutePath = packageDir.absoluteFilePath(filePath); + sourcePaths << baseDir.relativeFilePath(absolutePath); + } + } + + out << "The sources can be found in " << languageJoin(sourcePaths) << ".\n\n"; + + if (!package.homepage.isEmpty()) + out << "\\l{" << package.homepage << "}{Project Homepage}\n\n"; + + if (!package.copyright.isEmpty()) + out << "\n\\badcode\n" << package.copyright << "\n\\endcode\n\n"; + + if (isSpdxLicenseId(package.licenseId) && package.licenseId != QLatin1String("NONE")) + out << "\\l{https://spdx.org/licenses/" << package.licenseId << ".html}" + << "{" << package.license << "}.\n\n"; + else + out << package.license << ".\n\n"; + + if (!package.licenseFile.isEmpty()) { + QFile file(package.licenseFile); + if (!file.open(QIODevice::ReadOnly)) { + if (logLevel != SilentLog) + std::cerr << qPrintable(tr("Cannot open file %1.").arg( + QDir::toNativeSeparators(package.licenseFile))) << "\n"; + return; + } + out << "\\badcode\n"; + out << QString::fromUtf8(file.readAll()).trimmed(); + out << "\n\\endcode\n"; + } + out << "*/\n"; +} + +void generate(QTextStream &out, const QVector<Package> &packages, const QString &baseDirectory, + LogLevel logLevel) +{ + if (logLevel == VerboseLog) + std::cerr << qPrintable(tr("Generating qdoc file...")) << std::endl; + + QDir baseDir(baseDirectory); + for (const Package &package : packages) + generate(out, package, baseDir, logLevel); +} + +} // namespace QDocGenerator diff --git a/src/qtattributionsscanner/qdocgenerator.h b/src/qtattributionsscanner/qdocgenerator.h new file mode 100644 index 000000000..758318f13 --- /dev/null +++ b/src/qtattributionsscanner/qdocgenerator.h @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $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$ +** +****************************************************************************/ + +#ifndef QDOCGENERATOR_H +#define QDOCGENERATOR_H + +#include "logging.h" +#include "package.h" + +#include <QtCore/qtextstream.h> +#include <QtCore/qvector.h> + +namespace QDocGenerator { + +void generate(QTextStream &out, const QVector<Package> &packages, const QString &baseDirectory, + LogLevel logLevel); + +} // namespace QDocGenerator + +#endif // QDOCGENERATOR_H diff --git a/src/qtattributionsscanner/qtattributionsscanner.pro b/src/qtattributionsscanner/qtattributionsscanner.pro new file mode 100644 index 000000000..6bc20e419 --- /dev/null +++ b/src/qtattributionsscanner/qtattributionsscanner.pro @@ -0,0 +1,21 @@ +CONFIG += console + +SOURCES += \ + jsongenerator.cpp \ + main.cpp \ + packagefilter.cpp \ + qdocgenerator.cpp \ + scanner.cpp + +HEADERS += \ + jsongenerator.h \ + logging.h \ + package.h \ + packagefilter.h \ + qdocgenerator.h \ + scanner.h + +DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII + +option(host_build) +load(qt_tool) diff --git a/src/qtattributionsscanner/scanner.cpp b/src/qtattributionsscanner/scanner.cpp new file mode 100644 index 000000000..3babfbaef --- /dev/null +++ b/src/qtattributionsscanner/scanner.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $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$ +** +****************************************************************************/ + +#include "scanner.h" +#include "logging.h" + +#include <QtCore/qdir.h> +#include <QtCore/qjsonarray.h> +#include <QtCore/qjsondocument.h> +#include <QtCore/qjsonobject.h> +#include <QtCore/qvariant.h> + +#include <iostream> + +namespace Scanner { + +static void missingPropertyWarning(const QString &filePath, const QString &property) +{ + std::cerr << qPrintable(tr("File %1: Missing mandatory property '%2'.").arg( + QDir::toNativeSeparators(filePath), property)) << std::endl; +} + +static Package readPackage(const QJsonObject &object, const QString &filePath, LogLevel logLevel) +{ + Package p; + const QString directory = QFileInfo(filePath).absolutePath(); + p.path = directory; + + for (auto iter = object.constBegin(); iter != object.constEnd(); ++iter) { + const QString key = iter.key(); + + if (!iter.value().isString() && key != QLatin1String("files")) { + if (logLevel != SilentLog) + std::cerr << qPrintable(tr("File %1: Expected JSON string as value of %2.").arg( + QDir::toNativeSeparators(filePath), key)) << std::endl; + continue; + } + const QString value = iter.value().toString(); + if (key == QLatin1String("Name")) { + p.name = value; + } else if (key == QLatin1String("Path")) { + p.path = QDir(directory).absoluteFilePath(value); + } else if (key == QLatin1String("Files")) { + p.files = value.split(QRegExp(QStringLiteral("\\s")), QString::SkipEmptyParts); + } else if (key == QLatin1String("Id")) { + p.id = value; + } else if (key == QLatin1String("Homepage")) { + p.homepage = value; + } else if (key == QLatin1String("Version")) { + p.version = value; + } else if (key == QLatin1String("DownloadLocation")) { + p.downloadLocation = value; + } else if (key == QLatin1String("License")) { + p.license = value; + } else if (key == QLatin1String("LicenseId")) { + p.licenseId = value; + } else if (key == QLatin1String("LicenseFile")) { + p.licenseFile = QDir(directory).absoluteFilePath(value); + } else if (key == QLatin1String("Copyright")) { + p.copyright = value; + } else if (key == QLatin1String("QDocModule")) { + p.qdocModule = value; + } else if (key == QLatin1String("Description")) { + p.description = value; + } else if (key == QLatin1String("QtUsage")) { + p.qtUsage = value; + } else { + if (logLevel != SilentLog) + std::cerr << qPrintable(tr("File %1: Unknown key %2.").arg( + QDir::toNativeSeparators(filePath), key)) << std::endl; + } + } + + // Validate + if (logLevel != SilentLog) { + if (p.name.isEmpty()) + missingPropertyWarning(filePath, QStringLiteral("Name")); + if (p.id.isEmpty()) + missingPropertyWarning(filePath, QStringLiteral("Id")); + if (p.qdocModule.isEmpty()) + missingPropertyWarning(filePath, QStringLiteral("QDocModule")); + if (p.qtUsage.isEmpty()) + missingPropertyWarning(filePath, QStringLiteral("QtUsage")); + if (p.license.isEmpty()) + missingPropertyWarning(filePath, QStringLiteral("License")); + if (p.copyright.isEmpty()) + missingPropertyWarning(filePath, QStringLiteral("Copyright")); + } + return p; +} + +static QVector<Package> readFile(const QString &filePath, LogLevel logLevel) +{ + if (logLevel == VerboseLog) { + std::cerr << qPrintable(tr("Reading file %1...").arg( + QDir::toNativeSeparators(filePath))) << std::endl; + } + + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + if (logLevel != SilentLog) + std::cerr << qPrintable(tr("Could not open file %1.").arg( + QDir::toNativeSeparators(file.fileName()))) << std::endl; + return QVector<Package>(); + } + + QJsonParseError jsonParseError; + const QJsonDocument document = QJsonDocument::fromJson(file.readAll(), &jsonParseError); + if (document.isNull()) { + if (logLevel != SilentLog) + std::cerr << qPrintable(tr("Could not parse file %1: %2").arg( + QDir::toNativeSeparators(file.fileName()), + jsonParseError.errorString())) + << std::endl; + return QVector<Package>(); + } + + QVector<Package> packages; + if (document.isObject()) { + packages << readPackage(document.object(), file.fileName(), logLevel); + } else if (document.isArray()) { + QJsonArray array = document.array(); + for (int i = 0, size = array.size(); i < size; ++i) { + QJsonValue value = array.at(i); + if (value.isObject()) { + packages << readPackage(value.toObject(), file.fileName(), logLevel); + } else { + if (logLevel != SilentLog) + std::cerr << qPrintable(tr("File %1: Expecting JSON object in array.").arg( + QDir::toNativeSeparators(file.fileName()))) + << std::endl; + } + } + } else { + if (logLevel != SilentLog) + std::cerr << qPrintable(tr("File %1: Expecting JSON object in array.").arg( + QDir::toNativeSeparators(file.fileName()))) << std::endl; + } + return packages; +} + +QVector<Package> scanDirectory(const QString &directory, LogLevel logLevel) +{ + QDir dir(directory); + QVector<Package> packages; + + dir.setNameFilters(QStringList() << QStringLiteral("qt_attribution.json")); + dir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Files); + + foreach (const QFileInfo &info, dir.entryInfoList()) { + if (info.isDir()) { + packages += scanDirectory(info.filePath(), logLevel); + } else { + packages += readFile(info.filePath(), logLevel); + } + } + + return packages; +} + +} // namespace Scanner diff --git a/src/qtattributionsscanner/scanner.h b/src/qtattributionsscanner/scanner.h new file mode 100644 index 000000000..47d4aa6d9 --- /dev/null +++ b/src/qtattributionsscanner/scanner.h @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $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$ +** +****************************************************************************/ + +#ifndef SCANNER_H +#define SCANNER_H + +#include "logging.h" +#include "package.h" + +#include <QtCore/qstring.h> +#include <QtCore/qvector.h> + +namespace Scanner { + +QVector<Package> readDirectory(const QString &packageDirectory, LogLevel logLevel); +QVector<Package> scanDirectory(const QString &directory, LogLevel logLevel); + +} + +#endif // SCANNER_H diff --git a/src/qtestlib/qtestlib.pro b/src/qtestlib/qtestlib.pro deleted file mode 100644 index 2fcf35978..000000000 --- a/src/qtestlib/qtestlib.pro +++ /dev/null @@ -1,3 +0,0 @@ -TEMPLATE = subdirs -wince*: contains(QT_CONFIG, cetest): SUBDIRS += wince -CONFIG += ordered diff --git a/src/qtestlib/wince/cetcpsync/cetcpsync.pro b/src/qtestlib/wince/cetcpsync/cetcpsync.pro deleted file mode 100644 index ddfb44afa..000000000 --- a/src/qtestlib/wince/cetcpsync/cetcpsync.pro +++ /dev/null @@ -1,15 +0,0 @@ -CONFIG += console -QT += network -QT -= gui - -INCLUDEPATH += ../cetcpsyncserver - -SOURCES += main.cpp \ - remoteconnection.cpp \ - qtcesterconnection.cpp - -HEADERS += \ - remoteconnection.h \ - qtcesterconnection.h - -load(qt_app) diff --git a/src/qtestlib/wince/cetcpsync/main.cpp b/src/qtestlib/wince/cetcpsync/main.cpp deleted file mode 100644 index b302e4679..000000000 --- a/src/qtestlib/wince/cetcpsync/main.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ -#include <iostream> -#include "qtcesterconnection.h" - -using namespace std; - -static void showUsage() -{ - cout << "cetcpsync is meant to be used by cetest internally." << endl - << "For usage instructions remoteconnection.h could be useful." << endl; -} - -const int debugLevel = 0; -void debugOutput(const QString& text, int level) -{ - if (level <= debugLevel) - cout << qPrintable(text) << endl; -} - -class Exception -{ -public: - Exception(const QString& msg = QString()) - : m_message(msg) - {} - - QString message() { return m_message; } - -protected: - QString m_message; -}; - -class TooFewParametersException : public Exception -{ -public: - TooFewParametersException(const QLatin1String& cmd, int expectedParameterCount) - { - m_message = QLatin1String("Command ") + cmd + QLatin1String(" needs at least "); - m_message.append(QString::number(expectedParameterCount)); - m_message.append(QLatin1String(" parameters.")); - } -}; - -static void fileTimeFromString(FILETIME& ft, const QString& str) -{ - int idx = str.indexOf("*"); - if (idx <= 0) - return; - ft.dwLowDateTime = str.left(idx).toULong(); - ft.dwHighDateTime = str.mid(idx+1).toULong(); -} - -static QString fileTimeToString(FILETIME& ft) -{ - return QString::number(ft.dwLowDateTime) + "*" + QString::number(ft.dwHighDateTime); -} - -static int execCommand(const QLatin1String& cmd, int argc, char* argv[]) -{ - int retval = 0; - bool success = true; - QtCesterConnection connection; - if (cmd == "copyFileToDevice") { - if (argc < 3) - throw TooFewParametersException(cmd, 3); - success = connection.copyFileToDevice(argv[0], argv[1], argv[2] == "true"); - } else if (cmd == "copyDirectoryToDevice") { - if (argc < 3) - throw TooFewParametersException(cmd, 3); - success = connection.copyDirectoryToDevice(argv[0], argv[1], argv[2] == "true"); - } else if (cmd == "copyFileFromDevice") { - if (argc < 3) - throw TooFewParametersException(cmd, 3); - success = connection.copyFileFromDevice(argv[0], argv[1], argv[2] == "true"); - } else if (cmd == "copyDirectoryFromDevice") { - if (argc < 3) - throw TooFewParametersException(cmd, 3); - success = connection.copyDirectoryFromDevice(argv[0], argv[1], argv[2] == "true"); - } else if (cmd == "timeStampForLocalFileTime") { - if (argc < 1) - throw TooFewParametersException(cmd, 1); - FILETIME ft; - fileTimeFromString(ft, argv[0]); - success = connection.timeStampForLocalFileTime(&ft); - if (success) - cout << qPrintable(fileTimeToString(ft)); - } else if (cmd == "fileCreationTime") { - if (argc < 1) - throw TooFewParametersException(cmd, 1); - FILETIME ft; - success = connection.fileCreationTime(argv[0], &ft); - if (success) - cout << qPrintable(fileTimeToString(ft)); - } else if (cmd == "copyFile") { - if (argc < 3) - throw TooFewParametersException(cmd, 3); - success = connection.copyFile(argv[0], argv[1], argv[2] == "true"); - } else if (cmd == "copyDirectory") { - if (argc < 3) - throw TooFewParametersException(cmd, 3); - success = connection.copyDirectory(argv[0], argv[1], argv[2] == "true"); - } else if (cmd == "deleteFile") { - if (argc < 1) - throw TooFewParametersException(cmd, 1); - success = connection.deleteFile(argv[0]); - } else if (cmd == "deleteDirectory") { - if (argc < 3) - throw TooFewParametersException(cmd, 3); - success = connection.deleteDirectory(argv[0], argv[1] == "true", argv[2] == "true"); - } else if (cmd == "moveFile") { - if (argc < 3) - throw TooFewParametersException(cmd, 3); - success = connection.moveFile(argv[0], argv[1], argv[2] == "true"); - } else if (cmd == "moveDirectory") { - if (argc < 3) - throw TooFewParametersException(cmd, 3); - success = connection.moveDirectory(argv[0], argv[1], argv[2] == "true"); - } else if (cmd == "createDirectory") { - if (argc < 2) - throw TooFewParametersException(cmd, 2); - success = connection.createDirectory(argv[0], argv[1] == "true"); - } else if (cmd == "execute") { - if (argc < 3) - throw TooFewParametersException(cmd, 3); - int timeout = QString(argv[2]).toInt(); - success = connection.execute(argv[0], argv[1], timeout, &retval); - } else if (cmd == "noop") { - // do nothing :) - success = true; - } else { - throw Exception("unknown command"); - } - - return success ? retval : 1; -} - -int main(int argc, char *argv[]) -{ - if (argc <= 1) { - showUsage(); - return 0; - } - - QLatin1String param(argv[1]); - int result = 1; - try { - result = execCommand(param, argc - 2, argv + 2); - } catch (Exception e) { - cerr << "Error: " << qPrintable(e.message()); - } - return result; -} diff --git a/src/qtestlib/wince/cetcpsync/qtcesterconnection.cpp b/src/qtestlib/wince/cetcpsync/qtcesterconnection.cpp deleted file mode 100644 index 1fd05d1e0..000000000 --- a/src/qtestlib/wince/cetcpsync/qtcesterconnection.cpp +++ /dev/null @@ -1,550 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ -#include "qtcesterconnection.h" -#include <transfer_global.h> -#include <QtCore/QDir> -#include <QtCore/QFile> -#include <QtCore/QFileInfo> -#include <QtNetwork/QTcpSocket> -#include <QtNetwork/QHostAddress> - -extern void debugOutput(const QString& text, int level); - -#pragma warning(disable:4996) - -#define END_ERROR(s, a) \ - if(a) qDebug() << a; \ - _freeSocket(s); \ - return false; - -QtCesterConnection::QtCesterConnection() - : AbstractRemoteConnection() -{ -} - -QtCesterConnection::~QtCesterConnection() -{ -} - -bool QtCesterConnection::connect(QVariantList&) -{ - // We connect with each command, so this is always true - // The command itself will fail then - connected = true; - return true; -} - -void QtCesterConnection::disconnect() -{ - connected = false; -} - -bool QtCesterConnection::isConnected() const -{ - return connected; -} - -bool QtCesterConnection::copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists) -{ - debugOutput( qPrintable(QString::fromLatin1("Copy File: %1 -> %2").arg(localSource).arg(deviceDest)),0); - QFile localFile(localSource); - QFileInfo info(localSource); - if (!localFile.exists() || !localFile.open(QIODevice::ReadOnly)) { - qDebug() << "Could not open File!"; - return false; - } - - QTcpSocket* socket = 0; - if (!_initCommand(socket, COMMAND_CREATE_FILE)) { - END_ERROR(socket, "Could not initialized command"); - } - - CreateFileOptions option; - strcpy(option.fileName, qPrintable(deviceDest)); -#ifdef Q_OS_WIN - // Copy FileTime for update verification - FILETIME creationTime, accessTime, writeTime; - HANDLE localHandle = CreateFile(localSource.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); - if (localHandle != INVALID_HANDLE_VALUE) { - if (GetFileTime(localHandle, &creationTime, &accessTime, &writeTime)) { - LocalFileTimeToFileTime(&writeTime, &writeTime); - option.fileTime = writeTime; - } - CloseHandle(localHandle); - } - DWORD attributes = GetFileAttributes(localSource.utf16()); - if (attributes != -1 ) - option.fileAttributes = attributes; -#endif - option.fileSize = info.size(); - option.overwriteExisting = !failIfExists; - - if (!_sendData(socket, (char*) &option, sizeof(option))) { - END_ERROR(socket, "Could not send options..."); - } - - if (!_checkResult(socket)) { - END_ERROR(socket, "Server did not accept configuration"); - } - - int bytesWritten = 0; - const int bufferSize = 1024; - QByteArray data; - while (bytesWritten < option.fileSize) { - data = localFile.read(bufferSize); - bytesWritten += data.size(); -#ifdef Q_OS_WIN - wprintf( L"%s -> %s (%d / %d) %d %%\r", localSource.utf16() , deviceDest.utf16(), - bytesWritten , option.fileSize, (100*bytesWritten)/option.fileSize ); -#endif - if (!_sendData(socket, data.constData(), data.size())) { - END_ERROR(socket, "Error during file transfer"); - } - if (!_checkResult(socket)) { - END_ERROR(socket, "Got some strange result"); - } - } -#ifdef Q_OS_WIN - wprintf( L"\n"); // We should jump to next line... -#endif - if (bytesWritten != option.fileSize) { - END_ERROR(socket, "Did not send sufficient data"); - } - _freeSocket(socket); - return true; -} - -bool QtCesterConnection::copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive) -{ - QTcpSocket* socket = NULL; - QFileInfo info(localSource); - if (!info.exists() || !info.isDir()) { - END_ERROR(socket, "Input directory invalid"); - } - - createDirectory(deviceDest, true); - QDir dir(localSource); - QFileInfoList list = dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); - foreach(QFileInfo item, list) { - QString targetName = deviceDest + QLatin1String("\\") + item.fileName(); - if (item.isDir()) { - if (recursive) { - if (!copyDirectoryToDevice(item.absoluteFilePath() , targetName, recursive)) - return false; - } - } else { - if (!copyFileToDevice(item.absoluteFilePath(), targetName)) - return false; - } - } - return true; -} - -bool QtCesterConnection::copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists) -{ - QFile targetFile(localDest); - QTcpSocket* socket = 0; - if (targetFile.exists() && failIfExists) { - END_ERROR(socket, "Local file not supposed to be overwritten"); - } - - if (!targetFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { - END_ERROR(socket, "Could not open local file for writing"); - } - - if (!_initCommand(socket, COMMAND_READ_FILE)) { - END_ERROR(socket, "Could not establish connection"); - } - - ReadFileOptions option; - strcpy(option.fileName, qPrintable(deviceSource)); - if (!_sendData(socket, (char*) &option, sizeof(option))) { - END_ERROR(socket, "Could not send options"); - } - - QByteArray data; - if (!_receiveData(socket, data)) { - END_ERROR(socket, "Did not receive any data"); - } - - ReadFileReply* reply = (ReadFileReply*) data.data(); - if (!reply->fileValid) { - END_ERROR(socket, "Requested file invalid"); - } - - int fileSize = reply->fileSize; - int currentSize = 0; - // ### TODO: make a little bit more error-prone - do { - _sendData(socket, COMMAND_SUCCESS, strlen(COMMAND_SUCCESS)); - _receiveData(socket, data); - currentSize += data.size(); - targetFile.write(data); - } while(currentSize < fileSize); - - _freeSocket(socket); - targetFile.close(); - return true; -} - -bool QtCesterConnection::copyDirectoryFromDevice(const QString& /*deviceSource*/ - , const QString& /*localDest*/ - , bool /*recursive*/) -{ - qDebug() << "To be implemented!! Should not be needed for autotest system"; - exit(-1); - return false; -} - -bool QtCesterConnection::copyFile(const QString &srcFile, const QString &destFile, bool failIfExists) -{ - QTcpSocket* socket = 0; - if (!_initCommand(socket, COMMAND_COPY_FILE)) { - END_ERROR(socket, "Could not establish connection for copy"); - } - - CopyFileOptions option; - strcpy(option.from, qPrintable(srcFile)); - strcpy(option.to, qPrintable(destFile)); - option.overwriteExisting = !failIfExists; - if (!_sendData(socket, (char*) &option, sizeof(option))) { - END_ERROR(socket, "Could not send copy options"); - } - - if (!_checkResult(socket)) { - END_ERROR(socket, "Copy failed"); - } - - _freeSocket(socket); - return true; -} - -bool QtCesterConnection::copyDirectory(const QString &srcDirectory, const QString &destDirectory, - bool recursive) -{ - QTcpSocket* socket = 0; - if (!_initCommand(socket, COMMAND_COPY_DIRECTORY)) { - END_ERROR(socket, "Could not establish connection for dir copy"); - } - - CopyDirectoryOptions option; - strcpy(option.from, qPrintable(srcDirectory)); - strcpy(option.to, qPrintable(destDirectory)); - option.recursive = recursive; - if (!_sendData(socket, (char*) &option, sizeof(option))) { - END_ERROR(socket, "Could not send dir copy options"); - } - - if (!_checkResult(socket)) { - END_ERROR(socket, "Dir Copy failed"); - } - - _freeSocket(socket); - return true; -} - -bool QtCesterConnection::deleteFile(const QString &fileName) -{ - QTcpSocket* socket = 0; - if (!_initCommand(socket, COMMAND_DELETE_FILE)) { - END_ERROR(socket, "Could not establish connection for file deletion"); - } - - DeleteFileOptions option; - strcpy(option.fileName, qPrintable(fileName)); - if (!_sendData(socket, (char*) &option, sizeof(option))) { - END_ERROR(socket, "Could not send file options"); - } - - if (!_checkResult(socket)) { - //END_ERROR(socket, "File Deletion failed"); - // This is actually not an error so ignore it. - } - - _freeSocket(socket); - return true; -} - -bool QtCesterConnection::deleteDirectory(const QString &directory, bool recursive, bool failIfContentExists) -{ - QTcpSocket* socket = 0; - if (!_initCommand(socket, COMMAND_DELETE_DIRECTORY)) { - END_ERROR(socket, "Could not establish connection for dir deletion"); - } - - DeleteDirectoryOptions option; - strcpy(option.dirName, qPrintable(directory)); - option.recursive = recursive; - option.failIfContentExists = failIfContentExists; - if (!_sendData(socket, (char*) &option, sizeof(option))) { - END_ERROR(socket, "Could not send dir options"); - } - - if (!_checkResult(socket)) { - // we do not write an error as this will fail a lot on recursive. - END_ERROR(socket, 0); - } - - _freeSocket(socket); - return true; -} - -bool QtCesterConnection::execute(QString program, - QString arguments, - int timeout, - int *returnValue) -{ - QTcpSocket* socket = 0; - if (!_initCommand(socket, COMMAND_EXECUTE)) { - END_ERROR(socket, "Could not establish connection for dir deletion"); - } - - ExecuteOptions options; - strcpy(options.appName, qPrintable(program)); - QStringList argList = arguments.split(QLatin1Char(' ')); - options.argumentsCount = qMin(argList.size(), MAX_ARGUMENTS); - options.waitForFinished = true; - options.timeout = timeout; - if (!_sendData(socket, (char*) &options, sizeof(options))) { - END_ERROR(socket, "Could not send dir options"); - } - if (!_checkResult(socket)) { - END_ERROR(socket, "Did not receive an answer"); - } - - for (int i=0; i < options.argumentsCount; ++i) { - char someData[MAX_NAME_LENGTH]; - strcpy(someData, qPrintable(argList[i])); - if (!_sendData(socket, someData, MAX_NAME_LENGTH)) { - END_ERROR(socket, "Could not send argument"); - } - if (!_checkResult(socket)) { - END_ERROR(socket, "Failure in argument send"); - } - } - - // trigger the startup - if (!_sendData(socket, COMMAND_SUCCESS, strlen(COMMAND_SUCCESS))) { - END_ERROR(socket, "Could not trigger startup"); - } - - const int waitTime = 60 * 60 * 1000; - if (!socket->waitForReadyRead(waitTime)) { - END_ERROR(socket, "Process timed out"); - } - - QByteArray result = socket->readAll(); - if (result != COMMAND_SUCCESS) { - if (returnValue) - *returnValue = -1; // just some at least - END_ERROR(socket, "Application did not start or returned error"); - } - - if (returnValue) - *returnValue = 0; - _freeSocket(socket); - return true; -} - -bool QtCesterConnection::createDirectory(const QString &path, bool deleteBefore) -{ - if (deleteBefore) - deleteDirectory(path, true, true); - - QTcpSocket* socket = 0; - if (!_initCommand(socket, COMMAND_CREATE_DIRECTORY)) { - END_ERROR(socket, "Could not establish connection for dir creation"); - } - - CreateDirectoryOptions option; - strcpy(option.dirName, qPrintable(path)); - option.recursively = true; - if (!_sendData(socket, (char*) &option, sizeof(option))) { - END_ERROR(socket, "Could not send dir options"); - } - - if (!_checkResult(socket)) { - END_ERROR(socket, "Dir creation failed"); - } - - _freeSocket(socket); - return true; -} - -bool QtCesterConnection::timeStampForLocalFileTime(FILETIME* fTime) const -{ - if (!fTime) - return false; - - FILETIME copyTime = *fTime; - LocalFileTimeToFileTime(©Time, ©Time); - - QTcpSocket* socket = 0; - if (!_initCommand(socket, COMMAND_TIME_STAMP)) { - END_ERROR(socket, "Could not establish time stamp connection"); - } - - if (!_sendData(socket, (char*) ©Time, sizeof(copyTime))) { - END_ERROR(socket, "Could not send stamp time"); - } - - QByteArray data; - if (!_receiveData(socket, data)) { - END_ERROR(socket, "Did not receive time stamp or connection interrupted"); - } - - copyTime = *((FILETIME*)data.data()); - if (copyTime.dwLowDateTime == -1 && copyTime.dwHighDateTime == -1) { - END_ERROR(socket, "remote Time stamp failed!"); - } - - *fTime = copyTime; - _freeSocket(socket); - return true; -} - -bool QtCesterConnection::fileCreationTime(const QString &fileName, FILETIME* deviceCreationTime) const -{ - if (!deviceCreationTime) - return false; - - QTcpSocket* socket = 0; - if (!_initCommand(socket, COMMAND_FILE_TIME)) { - END_ERROR(socket, "Could not establish connection for file time access"); - } - - FileTimeOptions option; - strcpy(option.fileName, qPrintable(fileName)); - if (!_sendData(socket, (char*) &option, sizeof(option))) { - END_ERROR(socket, "Could not send file time name"); - } - - QByteArray data; - if (!_receiveData(socket, data)) { - END_ERROR(socket, "File Time request failed"); - } - - FILETIME* resultTime = (FILETIME*) data.data(); - if (resultTime->dwLowDateTime == -1 && resultTime->dwHighDateTime == -1) { - END_ERROR(socket, 0); - debugOutput("Could not access file time", 0); - } - - *deviceCreationTime = *resultTime; - _freeSocket(socket); - return true; -} - -bool QtCesterConnection::_createSocket(QTcpSocket*& result) const -{ - QTcpSocket* sock = new QTcpSocket(); - QByteArray ipAddress = qgetenv("DEVICE_IP"); - if (ipAddress.isEmpty()) { - qWarning("Error: You need to have DEVICE_IP set"); - exit(0); - } - sock->connectToHost(QHostAddress(QString(ipAddress)), 12145); - - if (!sock->waitForConnected()) { - qDebug() << "connection timeout..."; - result = NULL; - return false; - } - result = sock; - return true; -} - -void QtCesterConnection::_freeSocket(QTcpSocket*& sock) const -{ - if (!sock) - return; - if (sock->state() == QAbstractSocket::ConnectedState) { - sock->disconnectFromHost(); - // seems like no need to wait - //sock->waitForDisconnected(); - } - delete sock; - sock = NULL; -#ifdef Q_OS_WIN - Sleep(100); -#endif -} - -bool QtCesterConnection::_initCommand(QTcpSocket*& sock, const char* command) const -{ - QTcpSocket* socket = NULL; - if (!_createSocket(socket)) { - END_ERROR(socket, "Could not connect to server"); - } - - if (!_sendData(socket, command, strlen(command)) || - !_checkResult(socket)) { - END_ERROR(socket, "Cound not send command"); - } - sock = socket; - return true; -} - -bool QtCesterConnection::_sendData(QTcpSocket*& sock, const char* data, int dataSize) const -{ - int amount = sock->write(data, dataSize); - if (amount != dataSize) { - fprintf(stderr, "*******COULD NOT SEND ENOUGH DATA*************\n"); - } - return sock->waitForBytesWritten(); -} - -bool QtCesterConnection::_receiveData(QTcpSocket*& sock, QByteArray& data) const -{ - if (!sock->waitForReadyRead()) { - qDebug() << "did not receive any data"; - return false; - } - data = sock->readAll(); - return true; -} - -bool QtCesterConnection::_checkResult(QTcpSocket*& sock) const -{ - QByteArray response; - if (!_receiveData(sock, response) || response != COMMAND_SUCCESS) - return false; - return true; -} - diff --git a/src/qtestlib/wince/cetcpsync/qtcesterconnection.h b/src/qtestlib/wince/cetcpsync/qtcesterconnection.h deleted file mode 100644 index 453b96f24..000000000 --- a/src/qtestlib/wince/cetcpsync/qtcesterconnection.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ -#ifndef ACTIVESYNC_REMOTECONNECTION_H -#define ACTIVESYNC_REMOTECONNECTION_H - -#include "remoteconnection.h" - -class QTcpSocket; - -class QtCesterConnection : public AbstractRemoteConnection -{ -public: - QtCesterConnection(); - virtual ~QtCesterConnection(); - - bool connect(QVariantList &list = QVariantList()); - void disconnect(); - bool isConnected() const; - - // These functions are designed for transfer between desktop and device - // Caution: deviceDest path has to be device specific (eg. no drive letters for CE) - bool copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists = false); - bool copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive = true); - bool copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists = false); - bool copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive = true); - - bool timeStampForLocalFileTime(FILETIME*) const; - bool fileCreationTime(const QString &fileName, FILETIME*) const; - - // These functions only work on files existing on the device - bool copyFile(const QString&, const QString&, bool failIfExists = false); - bool copyDirectory(const QString&, const QString&, bool recursive = true); - bool deleteFile(const QString&); - bool deleteDirectory(const QString&, bool recursive = true, bool failIfContentExists = false); - bool createDirectory(const QString&, bool deleteBefore=false); - - bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL); -private: - bool _createSocket(QTcpSocket*&) const; - void _freeSocket(QTcpSocket*&) const; - bool _initCommand(QTcpSocket*&, const char*) const; - bool _sendData(QTcpSocket*&, const char* data, int dataSize) const; - bool _receiveData(QTcpSocket*&, QByteArray&) const; - bool _checkResult(QTcpSocket*&) const; - bool connected; -}; - -#endif diff --git a/src/qtestlib/wince/cetcpsync/remoteconnection.cpp b/src/qtestlib/wince/cetcpsync/remoteconnection.cpp deleted file mode 100644 index ebcf58430..000000000 --- a/src/qtestlib/wince/cetcpsync/remoteconnection.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ -#include "remoteconnection.h" - -AbstractRemoteConnection::AbstractRemoteConnection() -{ -} - -AbstractRemoteConnection::~AbstractRemoteConnection() -{ -} - -// Slow but should be ok... -bool AbstractRemoteConnection::moveFile(const QString &src, const QString &dest, bool FailIfExists) -{ - bool result = copyFile(src, dest, FailIfExists); - deleteFile(src); - return result; -} - -// Slow but should be ok... -bool AbstractRemoteConnection::moveDirectory(const QString &src, const QString &dest, bool recursive) -{ - bool result = copyDirectory(src, dest, true); - deleteDirectory(src, recursive); - return result; -} diff --git a/src/qtestlib/wince/cetcpsync/remoteconnection.h b/src/qtestlib/wince/cetcpsync/remoteconnection.h deleted file mode 100644 index bb894a4cf..000000000 --- a/src/qtestlib/wince/cetcpsync/remoteconnection.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ -#ifndef REMOTECONNECTION_H -#define REMOTECONNECTION_H - -#include <QtCore/QString> -#include <QtCore/QVariant> -#include <windows.h> -class AbstractRemoteConnection -{ -public: - AbstractRemoteConnection(); - virtual ~AbstractRemoteConnection(); - - virtual bool connect(QVariantList&) = 0; - virtual void disconnect() = 0; - virtual bool isConnected() const = 0; - - // These functions are designed for transfer between desktop and device - // Caution: deviceDest path has to be device specific (eg. no drive letters for CE) - virtual bool copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists = false) = 0; - virtual bool copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive = true) = 0; - virtual bool copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists = false) = 0; - virtual bool copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive = true) = 0; - - // For "intelligent deployment" we need to investigate on filetimes on the device - virtual bool timeStampForLocalFileTime(FILETIME*) const = 0; - virtual bool fileCreationTime(const QString &fileName, FILETIME*) const = 0; - - // These functions only work on files existing on the device - virtual bool copyFile(const QString&, const QString&, bool failIfExists = false) = 0; - virtual bool copyDirectory(const QString&, const QString&, bool recursive = true) = 0; - virtual bool deleteFile(const QString&) = 0; - virtual bool deleteDirectory(const QString&, bool recursive = true, bool failIfContentExists = false) = 0; - bool moveFile(const QString&, const QString&, bool FailIfExists = false); - bool moveDirectory(const QString&, const QString&, bool recursive = true); - - virtual bool createDirectory(const QString&, bool deleteBefore=false) = 0; - - virtual bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL) = 0; -}; - -#endif diff --git a/src/qtestlib/wince/cetcpsyncserver/cetcpsyncserver.pro b/src/qtestlib/wince/cetcpsyncserver/cetcpsyncserver.pro deleted file mode 100644 index 7d8b346e1..000000000 --- a/src/qtestlib/wince/cetcpsyncserver/cetcpsyncserver.pro +++ /dev/null @@ -1,17 +0,0 @@ -TARGET = cetcpsyncsvr -QT -= gui -QT += network - -CONFIG += console - -HEADERS += \ - connectionmanager.h \ - commands.h \ - transfer_global.h - -SOURCES += \ - connectionmanager.cpp \ - commands.cpp \ - main.cpp - -load(qt_app) diff --git a/src/qtestlib/wince/cetcpsyncserver/commands.cpp b/src/qtestlib/wince/cetcpsyncserver/commands.cpp deleted file mode 100644 index 005c76922..000000000 --- a/src/qtestlib/wince/cetcpsyncserver/commands.cpp +++ /dev/null @@ -1,684 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ -#include "commands.h" -#include <QtCore/QDebug> -#include <QtCore/QFileInfo> -#include <QtCore/QDir> -#include <QtCore/QProcess> - -#ifdef Q_OS_WINCE -#include <windows.h> -#endif - -///////////////////////////////////////////////////// -// Abstract Command Implementation // -///////////////////////////////////////////////////// -AbstractCommand::AbstractCommand() -: m_socket(0) -{ -} - -AbstractCommand::~AbstractCommand() -{ -} - -void AbstractCommand::reportSuccess() -{ - m_socket->write(COMMAND_SUCCESS, strlen(COMMAND_SUCCESS)); - m_socket->waitForBytesWritten(); -} - -void AbstractCommand::reportError() -{ - m_socket->write(COMMAND_ERROR, strlen(COMMAND_ERROR)); - m_socket->waitForBytesWritten(); -} - -void AbstractCommand::dataReceived(QByteArray&) -{ - debugOutput(1, "AbstractCommand::dataReceived NOT SUPPOSED TO BE HERE"); -} - -void AbstractCommand::commandFinished() -{ - debugOutput(1, "AbstractCommand::commandFinished()NOT SUPPOSED TO BE HERE"); -} - -void AbstractCommand::setSocket(QTcpSocket* socket) -{ - debugOutput(0, "AbstractCommand::setSocket()"); - Q_ASSERT(socket); - m_socket = socket; - connect(m_socket, SIGNAL(readyRead()), this, SLOT(_readData())); - reportSuccess(); -} - -QTcpSocket* AbstractCommand::socket() -{ - return m_socket; -} - -void AbstractCommand::_readData() -{ - QByteArray arr = m_socket->readAll(); - dataReceived(arr); -} - -void AbstractCommand::_disconnect() -{ -} - -///////////////////////////////////////////////////// -// Create File Command Implementation // -///////////////////////////////////////////////////// -CreateFileCommand::CreateFileCommand() -: m_dataCount(0) -{ - debugOutput(0, "CreateFileCommand::CreateFileCommand"); - m_options.fileSize= -1; -} - -CreateFileCommand::~CreateFileCommand() -{ - debugOutput(0, "CreateFileCommand::~CreateFileCommand"); - if (m_file.isOpen()) { - fprintf(stderr, "****************FILE IS STILL OPENED AND HAVENT FINISHED WRITING**********************\n"); - fprintf(stderr, "Current: %d Expected: %d\n", m_dataCount , m_options.fileSize); - m_file.close(); - } -} - -void CreateFileCommand::dataReceived(QByteArray &data) -{ - bool successful = true; - // If we haven't received the options yet - if (m_options.fileSize == -1) { - CreateFileOptions* opt = (CreateFileOptions*) data.data(); - memcpy(&m_options , opt , sizeof(CreateFileOptions)); - - if (QFileInfo(QString::fromLatin1(m_options.fileName)).exists()) { - if (m_options.overwriteExisting) { -#ifdef Q_OS_WINCE - SetFileAttributes(QFileInfo(m_options.fileName).absoluteFilePath().utf16(), FILE_ATTRIBUTE_NORMAL); -#endif - QFile::remove(m_options.fileName); - } else - successful = false; - } - m_file.setFileName(QString::fromLatin1(m_options.fileName)); - if (!m_file.open(QIODevice::WriteOnly)) - successful = false; - else - debugOutput(3, QString::fromLatin1("Creating file: %1").arg(m_options.fileName)); - } else { // write buffer on disc - if (!m_file.isOpen()) - return; - m_file.write(data); - m_dataCount += data.size(); - if (m_dataCount >= m_options.fileSize) { - // We do not care about more data than announced - m_file.close(); - } - } - - if (successful) - reportSuccess(); - else - reportError(); -} - -void CreateFileCommand::commandFinished() -{ - debugOutput(0, "CreateFileCommand::commandFinished"); -#ifdef Q_OS_WIN - // We need to set the file attributes for intelligent time comparisons - QString tmpFile = QString::fromLatin1(m_options.fileName); - HANDLE handle = CreateFile(tmpFile.utf16(), GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - if (handle != INVALID_HANDLE_VALUE) { - SetFileTime(handle, &(m_options.fileTime), NULL, NULL); - CloseHandle(handle); - } - SetFileAttributes(tmpFile.utf16(), m_options.fileAttributes); -#endif -} - -///////////////////////////////////////////////////// -// Create Directory Command Implementation // -///////////////////////////////////////////////////// -CreateDirectoryCommand::CreateDirectoryCommand() - : AbstractCommand() -{ - debugOutput(0, "CreateDirectoryCommand::CreateDirectoryCommand"); -} - -CreateDirectoryCommand::~CreateDirectoryCommand() -{ - debugOutput(0, "CreateDirectoryCommand::~CreateDirectoryCommand()"); -} - -void CreateDirectoryCommand::dataReceived(QByteArray &data) -{ - debugOutput(0, "CreateDirectoryCommand::dataReceived()"); - CreateDirectoryOptions* options = (CreateDirectoryOptions*) data.data(); - debugOutput(3, QString::fromLatin1("Creating directory: %1").arg(options->dirName)); - bool success = true; - QDir dir; - if (options->recursively) - success = dir.mkpath(options->dirName); - else - success = dir.mkdir(options->dirName); - - if (success) - reportSuccess(); - else - reportError(); -} - -void CreateDirectoryCommand::commandFinished() -{ - debugOutput(0, "CreateDirectoryCommand::commandFinished()"); -} - -///////////////////////////////////////////////////// -// Copy File Command Implementation // -///////////////////////////////////////////////////// -CopyFileCommand::CopyFileCommand() - : AbstractCommand() -{ - debugOutput(0, "CopyFileCommand::CopyFileCommand()"); -} - -CopyFileCommand::~CopyFileCommand() -{ - debugOutput(0, "CopyFileCommand::~CopyFileCommand()"); -} - -void CopyFileCommand::dataReceived(QByteArray &data) -{ - debugOutput(0, "CopyFileCommand::dataReceived()"); - CopyFileOptions* options = (CopyFileOptions*) data.data(); - debugOutput(3, QString::fromLatin1("Copy File: %1 -> %2").arg(options->from).arg(options->to)); - bool success = true; - if (QFileInfo(options->to).exists()) { - if (options->overwriteExisting) - QFile::remove(options->to); - else - success = false; - } - if (success) - if (!QFile::copy(options->from , options->to)) - success = false; - - if (success) - reportSuccess(); - else - reportError(); -} - -void CopyFileCommand::commandFinished() -{ - debugOutput(0, "CopyFileCommand::commandFinished()"); -} - -///////////////////////////////////////////////////// -// Copy Directory Command Implementation // -///////////////////////////////////////////////////// -CopyDirectoryCommand::CopyDirectoryCommand() - : AbstractCommand() -{ - debugOutput(0, "CopyDirectoryCommand::CopyDirectoryCommand()"); -} - -CopyDirectoryCommand::~CopyDirectoryCommand() -{ - debugOutput(0, "CopyDirectoryCommand::~CopyDirectoryCommand()"); -} - -void CopyDirectoryCommand::dataReceived(QByteArray &data) -{ - debugOutput(0, "CopyDirectoryCommand::dataReceived()"); - CopyDirectoryOptions* options = (CopyDirectoryOptions*) data.data(); - debugOutput(3, QString::fromLatin1("Copy Directory: %1 %2").arg(options->from).arg(options->to)); - if (copyDir(QLatin1String(options->from) , QLatin1String(options->to) , options->recursive)) - reportSuccess(); - else - reportError(); -} - -void CopyDirectoryCommand::commandFinished() -{ - debugOutput(0, "CopyDirectoryCommand::commandFinished()"); -} - -bool CopyDirectoryCommand::copyDir(const QString &from, const QString &to, bool recursive) -{ - QDir().mkpath(to); - QDir sourceDir(from); - QDir destDir(to); - QStringList entries = sourceDir.entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot); - foreach (QString item , entries) { - QString itemFrom = sourceDir.absoluteFilePath(item); - QString itemTo = destDir.absoluteFilePath(item); - if (QFileInfo(item).isDir()) { - if (recursive && !copyDir(itemFrom, itemTo, recursive)) - return false; - } else { - if (!QFile::copy(itemFrom, itemTo)) - return false; - } - } - return true; -} - -///////////////////////////////////////////////////// -// Delete File Command Implementation // -///////////////////////////////////////////////////// -DeleteFileCommand::DeleteFileCommand() - : AbstractCommand() -{ - debugOutput(0, "DeleteFileCommand::DeleteFileCommand()"); -} - -DeleteFileCommand::~DeleteFileCommand() -{ - debugOutput(0, "DeleteFileCommand::~DeleteFileCommand()"); -} - -void DeleteFileCommand::dataReceived(QByteArray &data) -{ - debugOutput(0, "DeleteFileCommand::dataReceived()"); - DeleteFileOptions* options = (DeleteFileOptions*) data.data(); - debugOutput(3, QString::fromLatin1("Delete File: %1").arg(options->fileName)); - bool success = true; - QFile file(options->fileName); - if (file.exists()) { -#ifdef Q_OS_WINCE - SetFileAttributes(QFileInfo(options->fileName).absoluteFilePath().utf16(), FILE_ATTRIBUTE_NORMAL); -#endif - success = file.remove(); - } else - success = false; - - if (success) - reportSuccess(); - else - reportError(); -} - -void DeleteFileCommand::commandFinished() -{ - debugOutput(0, "DeleteFileCommand::commandFinished()"); -} - -///////////////////////////////////////////////////// -// Delete Directory Command Implementation // -///////////////////////////////////////////////////// -DeleteDirectoryCommand::DeleteDirectoryCommand() - : AbstractCommand() -{ - debugOutput(0, "DeleteDirectoryCommand::DeleteDirectoryCommand()"); -} - -DeleteDirectoryCommand::~DeleteDirectoryCommand() -{ - debugOutput(0, "DeleteDirectoryCommand::~DeleteDirectoryCommand()"); -} - -void DeleteDirectoryCommand::dataReceived(QByteArray &data) -{ - debugOutput(0, "DeleteDirectoryCommand::dataReceived()"); - DeleteDirectoryOptions* options = (DeleteDirectoryOptions*) data.data(); - debugOutput(3, QString::fromLatin1("Delete directory: %1").arg(options->dirName)); - if (deleteDirectory(QLatin1String(options->dirName), options->recursive, options->failIfContentExists)) - reportSuccess(); - else - reportError(); -} - -void DeleteDirectoryCommand::commandFinished() -{ - debugOutput(0, "DeleteDirectoryCommand::commandFinished()"); -} - -bool DeleteDirectoryCommand::deleteDirectory(const QString &dirName, bool recursive, bool failIfContentExists) -{ - QDir dir(dirName); - if (!dir.exists()) - return false; - - QStringList itemList = dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); - if (itemList.size() > 0 && failIfContentExists) - return false; - - foreach (QString item, itemList) { - QString itemName = dir.absoluteFilePath(item); - if (QFileInfo(itemName).isDir()) { - if (recursive && !deleteDirectory(itemName, recursive, failIfContentExists)) - return false; - } else { - if (!dir.remove(item)) - return false; - } - } - QString lastName = dir.dirName(); - dir.cdUp(); - dir.rmpath(lastName); - return true; -} - -///////////////////////////////////////////////////// -// Execute Command Implementation // -///////////////////////////////////////////////////// -ExecuteCommand::ExecuteCommand() - : AbstractCommand() - , m_argumentCount(0) - , m_timeout(-1) -{ - debugOutput(0, "ExecuteCommand::ExecuteCommand()"); -} - -ExecuteCommand::~ExecuteCommand() -{ - debugOutput(0, "ExecuteCommand::~ExecuteCommand()"); -} - -void ExecuteCommand::dataReceived(QByteArray &data) -{ - debugOutput(0, "ExecuteCommand::dataReceived()"); - - if (m_argumentCount == 0) { - ExecuteOptions* options = (ExecuteOptions*) data.data(); - if (!QFileInfo(options->appName).exists()) { - debugOutput(1, "Error execute: application does not exist"); - reportError(); - return; - } - - m_program = QLatin1String(options->appName); - m_argumentCount = options->argumentsCount; - m_waitFinished = options->waitForFinished; - m_timeout = options->timeout; - if (m_argumentCount == 0) - m_argumentCount = -1; // to trigger startup on next receive - reportSuccess(); - } else if (m_arguments.size() < m_argumentCount) { - m_arguments += data; - reportSuccess(); - } else { // do the execution - if (data == COMMAND_SUCCESS) - _doExecute(); - } -} - -void ExecuteCommand::_doExecute() -{ - debugOutput(0, "ExecuteCommand::_doExecute()"); - debugOutput(3, QString::fromLatin1("Execute: %1 %2").arg(m_program).arg(m_arguments.join(" "))); - if (m_waitFinished) { - QProcess process; - process.start(m_program, m_arguments); - if (process.waitForFinished(m_timeout) == false || process.exitCode() < 0) - reportError(); - else - reportSuccess(); - } else { - if (QProcess::startDetached(m_program, m_arguments)) - reportSuccess(); - else - reportError(); - } -} -void ExecuteCommand::commandFinished() -{ - debugOutput(0,"ExecuteCommand::commandFinished()"); -} - -///////////////////////////////////////////////////// -// Read File Implementation // -///////////////////////////////////////////////////// -ReadFileCommand::ReadFileCommand() - : AbstractCommand() - , m_currentPos(0) -{ - debugOutput(0, "ReadFileCommand::ReadFileCommand()"); - m_fileName.clear(); -} - -ReadFileCommand::~ReadFileCommand() -{ - debugOutput(0, "ReadFileCommand::~ReadFileCommand()"); - if (m_file.isOpen()) - m_file.close(); -} - -void ReadFileCommand::dataReceived(QByteArray &data) -{ - debugOutput(0, "ReadFileCommand::dataReceived()"); - if (m_fileName.isEmpty()) { - ReadFileOptions* option = (ReadFileOptions*) data.data(); - m_fileName = QLatin1String(option->fileName); - QFileInfo info(m_fileName); - m_file.setFileName(m_fileName); - ReadFileReply reply; - if (!info.exists() || !info.isFile() || !m_file.open(QIODevice::ReadOnly)) - reply.fileValid = false; - else - reply.fileValid = true; - reply.fileSize = info.size(); - m_fileSize = reply.fileSize; - socket()->write((char*) &reply, sizeof(reply)); - debugOutput(3, QString::fromLatin1("Reading file: %1").arg(m_fileName)); - } else { - QTcpSocket* sock = socket(); // design failure??? - if (data != COMMAND_SUCCESS || m_currentPos >= m_fileSize) { - sock->disconnectFromHost(); - return; - } - const int bufferSize = 1024; - QByteArray buffer = m_file.read(bufferSize); - m_currentPos += buffer.size(); - sock->write(buffer); - sock->waitForBytesWritten(); - } -} - -void ReadFileCommand::commandFinished() -{ - debugOutput(0, "ReadFileCommand::commandFinished()"); -} - -///////////////////////////////////////////////////// -// Read Directory Implementation // -///////////////////////////////////////////////////// -ReadDirectoryCommand::ReadDirectoryCommand() - : AbstractCommand() - , m_iterator(0) -{ - debugOutput(0, "ReadDirectoryCommand::ReadDirectoryCommand"); - m_dirName.clear(); -} - -ReadDirectoryCommand::~ReadDirectoryCommand() -{ - debugOutput(0, "ReadDirectoryCommand::~ReadDirectoryCommand()"); - delete m_iterator; -} - -void ReadDirectoryCommand::dataReceived(QByteArray &data) -{ - debugOutput(0, "ReadDirectoryCommand::dataReceived()"); - QTcpSocket* sock = socket(); - if (m_dirName.isEmpty()) { - ReadDirectoryOptions* option = (ReadDirectoryOptions*) data.data(); - QFileInfo info(QLatin1String(option->dirName)); - debugOutput(3, QString::fromLatin1("Reading Directory entries: %1").arg(option->dirName)); - ReadDirectoryReply reply; - if (!info.exists() || !info.isDir()) { - reply.itemCount = -1; - reply.entryValid = false; - } else { - m_dirName = QLatin1String(option->dirName); - m_dir.setPath(m_dirName); - m_iterator = new QDirIterator(m_dir); - reply.itemCount = m_dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot).size(); - reply.entryValid = true; - } - sock->write((char*) &reply, sizeof(reply)); - sock->waitForBytesWritten(); - } else { - if (data != COMMAND_SUCCESS) { - qDebug() << "Something went wrong in the meantime"; - return; - } - ReadDirectoryItem reply; - if (m_iterator->hasNext()) { - m_iterator->next(); - QFileInfo info = m_iterator->fileInfo(); - strcpy(reply.name, qPrintable(info.absoluteFilePath())); - reply.isDirectory = info.isDir(); - if (!reply.isDirectory) - reply.size = info.size(); - } - reply.hasMore = m_iterator->hasNext(); - sock->write((char*) &reply, sizeof(reply)); - sock->waitForBytesWritten(); - } -} - -void ReadDirectoryCommand::commandFinished() -{ - debugOutput(0, "ReadDirectoryCommand::commandFinished()"); -} - -///////////////////////////////////////////////////// -// File Time Implementation // -///////////////////////////////////////////////////// -FileTimeCommand::FileTimeCommand() - : AbstractCommand() -{ - debugOutput(0, "FileTimeCommand::FileTimeCommand()"); -} - -FileTimeCommand::~FileTimeCommand() -{ - debugOutput(0, "FileTimeCommand::~FileTimeCommand()"); -} - -void FileTimeCommand::dataReceived(QByteArray &data) -{ - debugOutput(0, "FileTimeCommand::dataReceived()"); - FileTimeOptions* option = (FileTimeOptions*) data.data(); - - FILETIME resultTime; - resultTime.dwLowDateTime = -1; - resultTime.dwHighDateTime = -1; - -#ifdef Q_OS_WIN - QString fileName = QLatin1String(option->fileName); - HANDLE deviceHandle = CreateFile(fileName.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); - debugOutput(3, QString::fromLatin1("Asking FileTime: %1").arg(fileName)); - if (deviceHandle != INVALID_HANDLE_VALUE) { - FILETIME deviceCreationTime; - if (GetFileTime(deviceHandle, &deviceCreationTime, NULL, NULL)) { - resultTime = deviceCreationTime; - } - CloseHandle(deviceHandle); - } -#endif - QTcpSocket* sock = socket(); - sock->write((char*) &resultTime, sizeof(resultTime)); - sock->waitForBytesWritten(); -} - -void FileTimeCommand::commandFinished() -{ - debugOutput(0, "FileTimeCommand::commandFinished()"); -} - -///////////////////////////////////////////////////// -// Time Stamp Implementation // -///////////////////////////////////////////////////// -TimeStampCommand::TimeStampCommand() - : AbstractCommand() -{ - debugOutput(0, "TimeStampCommand::TimeStampCommand()"); -} - -TimeStampCommand::~TimeStampCommand() -{ - debugOutput(0, "TimeStampCommand::~TimeStampCommand()"); -} - -void TimeStampCommand::dataReceived(QByteArray &data) -{ - debugOutput(0, "TimeStampCommand::dataReceived()"); - FILETIME resultTime; - resultTime.dwLowDateTime = -1; - resultTime.dwHighDateTime = -1; - -#ifdef Q_OS_WIN - FILETIME stampTime = *((FILETIME*)data.data()); - - QString tmpFile = QString::fromLatin1("\\qt_tmp_ftime_convert"); - HANDLE remoteHandle = CreateFile(tmpFile.utf16(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); - if (remoteHandle != INVALID_HANDLE_VALUE) { - if (!SetFileTime(remoteHandle, &stampTime, NULL, NULL)) { - CloseHandle(remoteHandle); - } else { - CloseHandle(remoteHandle); - remoteHandle = CreateFile(tmpFile.utf16(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); - if (remoteHandle != INVALID_HANDLE_VALUE) { - if (GetFileTime(remoteHandle, &stampTime, NULL, NULL)) - resultTime = stampTime; - CloseHandle(remoteHandle); - DeleteFile(tmpFile.utf16()); - } - } - } - debugOutput(3, QString::fromLatin1("Asking TimeStamp")); -#endif - QTcpSocket* sock = socket(); - sock->write((char*) &resultTime, sizeof(resultTime)); - sock->waitForBytesWritten(); -} - -void TimeStampCommand::commandFinished() -{ - debugOutput(0, "TimeStampCommand::commandFinished()"); -} diff --git a/src/qtestlib/wince/cetcpsyncserver/commands.h b/src/qtestlib/wince/cetcpsyncserver/commands.h deleted file mode 100644 index b3b41585b..000000000 --- a/src/qtestlib/wince/cetcpsyncserver/commands.h +++ /dev/null @@ -1,290 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ -#ifndef COMMANDS_INCL -#define COMMANDS_INCL - -#include "transfer_global.h" - -#include <QtNetwork/QTcpSocket> -#include <QtCore/QString> -#include <QtCore/QFile> -#include <QtCore/QDir> -#include <QtCore/QDirIterator> -#include <windows.h> - -// debug output -#define DEBUG_LEVEL 2 -inline void debugOutput(int level, const char* text) -{ - if (level >= DEBUG_LEVEL) - qDebug() << text; -} - -inline void debugOutput(int level, const QString &text) -{ - if (level >= DEBUG_LEVEL) - qDebug() << text; -} -// Basic abtract command class -class AbstractCommand : public QObject -{ - Q_OBJECT -public: - AbstractCommand(); - virtual ~AbstractCommand(); - - void setSocket(QTcpSocket*); - QTcpSocket* socket(); - - void reportSuccess(); - void reportError(); - -public slots: - virtual void dataReceived(QByteArray&); - virtual void commandFinished(); - -private slots: - void _readData(); - void _disconnect(); - -private: - QTcpSocket* m_socket; -}; - -// File Creation class -class CreateFileCommand : public AbstractCommand -{ - Q_OBJECT -public: - CreateFileCommand(); - ~CreateFileCommand(); - -public slots: - void dataReceived(QByteArray&); - void commandFinished(); - -private: - CreateFileOptions m_options; - QFile m_file; - int m_dataCount; -}; - -inline AbstractCommand* instCreateFile() { return new CreateFileCommand(); } - -// Directory Creation class -class CreateDirectoryCommand : public AbstractCommand -{ - Q_OBJECT -public: - CreateDirectoryCommand(); - ~CreateDirectoryCommand(); - -public slots: - void dataReceived(QByteArray&); - void commandFinished(); -}; -inline AbstractCommand* instCreateDirectory() { return new CreateDirectoryCommand(); } - -// File copy class -class CopyFileCommand : public AbstractCommand -{ - Q_OBJECT -public: - CopyFileCommand(); - ~CopyFileCommand(); - -public slots: - void dataReceived(QByteArray&); - void commandFinished(); -}; -inline AbstractCommand* instCopyFile() { return new CopyFileCommand(); } - -// Copy directory class -class CopyDirectoryCommand : public AbstractCommand -{ - Q_OBJECT -public: - CopyDirectoryCommand(); - ~CopyDirectoryCommand(); - -public slots: - void dataReceived(QByteArray&); - void commandFinished(); -private: - bool copyDir(const QString &from, const QString &to, bool recursive); -}; -inline AbstractCommand* instCopyDirectory() { return new CopyDirectoryCommand(); } - -// Delete File class -class DeleteFileCommand : public AbstractCommand -{ - Q_OBJECT -public: - DeleteFileCommand(); - ~DeleteFileCommand(); -public slots: - void dataReceived(QByteArray&); - void commandFinished(); -}; -inline AbstractCommand* instDeleteFile() { return new DeleteFileCommand(); } - -// Delete Directory class -class DeleteDirectoryCommand : public AbstractCommand -{ - Q_OBJECT -public: - DeleteDirectoryCommand(); - ~DeleteDirectoryCommand(); -public slots: - void dataReceived(QByteArray&); - void commandFinished(); -private: - bool deleteDirectory(const QString &dirName, bool recursive, bool failIfContentExists); -}; -inline AbstractCommand* instDeleteDirectory() { return new DeleteDirectoryCommand(); } - -// Execute application class -class ExecuteCommand : public AbstractCommand -{ - Q_OBJECT -public: - ExecuteCommand(); - ~ExecuteCommand(); -public slots: - void dataReceived(QByteArray&); - void commandFinished(); -private: - void _doExecute(); - QString m_program; - QStringList m_arguments; - int m_argumentCount; - bool m_waitFinished; - int m_timeout; -}; -inline AbstractCommand* instExecution() { return new ExecuteCommand(); } - -// Read File class -class ReadFileCommand : public AbstractCommand -{ - Q_OBJECT -public: - ReadFileCommand(); - ~ReadFileCommand(); -public slots: - void dataReceived(QByteArray&); - void commandFinished(); -private: - QString m_fileName; - QFile m_file; - qint64 m_currentPos; - qint64 m_fileSize; -}; -inline AbstractCommand* instReadFile() { return new ReadFileCommand(); } - -// Read Directory class -class ReadDirectoryCommand : public AbstractCommand -{ - Q_OBJECT -public: - ReadDirectoryCommand(); - ~ReadDirectoryCommand(); -public slots: - void dataReceived(QByteArray&); - void commandFinished(); -private: - QString m_dirName; - QDir m_dir; - QDirIterator* m_iterator; -}; -inline AbstractCommand* instReadDirectory() { return new ReadDirectoryCommand(); } - -// Read File Time class -class FileTimeCommand : public AbstractCommand -{ - Q_OBJECT -public: - FileTimeCommand(); - ~FileTimeCommand(); -public slots: - void dataReceived(QByteArray&); - void commandFinished(); -}; -inline AbstractCommand* instFileTime() { return new FileTimeCommand(); } - -// Time stamp class -class TimeStampCommand : public AbstractCommand -{ - Q_OBJECT -public: - TimeStampCommand(); - ~TimeStampCommand(); -public slots: - void dataReceived(QByteArray&); - void commandFinished(); -}; -inline AbstractCommand* instTimeStamp() { return new TimeStampCommand(); } - -// Access part -typedef AbstractCommand* (*instantiator)(); - -struct CommandInfo -{ - CommandInfo(const QString &name, instantiator func) : commandName(name) , commandFunc(func) { } - QString commandName; - instantiator commandFunc; -}; - -inline QList<CommandInfo> availableCommands() -{ - QList<CommandInfo> list; - list.append(CommandInfo(QLatin1String(COMMAND_CREATE_FILE), instCreateFile)); - list.append(CommandInfo(QLatin1String(COMMAND_CREATE_DIRECTORY), instCreateDirectory)); - list.append(CommandInfo(QLatin1String(COMMAND_COPY_FILE), instCopyFile)); - list.append(CommandInfo(QLatin1String(COMMAND_COPY_DIRECTORY), instCopyDirectory)); - list.append(CommandInfo(QLatin1String(COMMAND_DELETE_FILE), instDeleteFile)); - list.append(CommandInfo(QLatin1String(COMMAND_DELETE_DIRECTORY), instDeleteDirectory)); - list.append(CommandInfo(QLatin1String(COMMAND_EXECUTE), instExecution)); - list.append(CommandInfo(QLatin1String(COMMAND_READ_FILE), instReadFile)); - list.append(CommandInfo(QLatin1String(COMMAND_READ_DIRECTORY), instReadDirectory)); - list.append(CommandInfo(QLatin1String(COMMAND_FILE_TIME), instFileTime)); - list.append(CommandInfo(QLatin1String(COMMAND_TIME_STAMP), instTimeStamp)); - return list; -} - -#endif diff --git a/src/qtestlib/wince/cetcpsyncserver/connectionmanager.cpp b/src/qtestlib/wince/cetcpsyncserver/connectionmanager.cpp deleted file mode 100644 index 22391d087..000000000 --- a/src/qtestlib/wince/cetcpsyncserver/connectionmanager.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ -#include "connectionmanager.h" -#include "commands.h" -#include <QtCore/QDebug> - -ConnectionManager::ConnectionManager() - : QObject() - , m_server(0) -{ - debugOutput(0, "ConnectionManager::ConnectionManager()"); -} - -ConnectionManager::~ConnectionManager() -{ - debugOutput(0, "ConnectionManager::~ConnectionManager()"); - cleanUp(); -} - -bool ConnectionManager::init() -{ - debugOutput(0, "ConnectionManager::init()"); - debugOutput(3, "Initializing server..."); - cleanUp(); - m_server = new QTcpServer(this); - connect(m_server, SIGNAL(newConnection()), this, SLOT(newConnection())); - bool result = m_server->listen(QHostAddress::Any, SERVER_PORT); - if (!result) - debugOutput(3, QString::fromLatin1(" Error: Server start failed:") + m_server->errorString()); - debugOutput(3, " Waiting for action"); - return result; -} - -void ConnectionManager::cleanUp() -{ - debugOutput(0, "ConnectionManager::cleanUp()"); - - if (m_server) { - debugOutput(1, "Removing server instance..."); - disconnect(m_server, SIGNAL(newConnection()), this, SLOT(newConnection())); - delete m_server; - m_server = 0; - } -} - -void ConnectionManager::newConnection() -{ - debugOutput(0, "ConnectionManager::newConnection()"); - - QTcpSocket* connection = m_server->nextPendingConnection(); - if (!connection) { - debugOutput(3, "Received connection has empty socket"); - return; - } - debugOutput(0, QString::fromLatin1(" received a connection: %1").arg((int) connection)); - new Connection(connection); -} - -Connection::Connection(QTcpSocket *socket) - : QObject() - , m_connection(socket) - , m_command(0) -{ - connect(m_connection, SIGNAL(readyRead()), this, SLOT(receiveCommand())); - connect(m_connection, SIGNAL(disconnected()), this, SLOT(closedConnection())); -} - -Connection::~Connection() -{ - if (m_command) { - m_command->commandFinished(); - delete m_command; - m_command = 0; - } - delete m_connection; -} - -void Connection::receiveCommand() -{ - QByteArray arr = m_connection->readAll(); - debugOutput(1, QString::fromLatin1("Command received: ") + (arr)); - QList<CommandInfo> commands = availableCommands(); - for(QList<CommandInfo>::iterator it = commands.begin(); it != commands.end(); ++it) { - if (it->commandName == QString::fromLatin1(arr)) { - debugOutput(1, "Found command in list"); - disconnect(m_connection, SIGNAL(readyRead()), this, SLOT(receiveCommand())); - AbstractCommand* command = (*it).commandFunc(); - command->setSocket(m_connection); - m_command = command; - return; - } - } - debugOutput(2, QString::fromLatin1("Unknown command received: ") + (arr)); -} - -void Connection::closedConnection() -{ - debugOutput(0, "connection being closed..."); - this->deleteLater(); -} diff --git a/src/qtestlib/wince/cetcpsyncserver/connectionmanager.h b/src/qtestlib/wince/cetcpsyncserver/connectionmanager.h deleted file mode 100644 index e52109a91..000000000 --- a/src/qtestlib/wince/cetcpsyncserver/connectionmanager.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ -#ifndef CONNECTION_MANAGER_INCL -#define CONNECTION_MANAGER_INCL - -#include "transfer_global.h" -#include "commands.h" - -#include <QtNetwork/QTcpServer> -#include <QtNetwork/QTcpSocket> - -class Connection : public QObject -{ - Q_OBJECT -public: - Connection(QTcpSocket* socket); - ~Connection(); - -public slots: - void receiveCommand(); - void closedConnection(); - -private: - QTcpSocket* m_connection; - AbstractCommand* m_command; -}; - -class ConnectionManager : public QObject -{ - Q_OBJECT -public: - ConnectionManager(); - ~ConnectionManager(); - - bool init(); - -public slots: - void cleanUp(); - void newConnection(); - -private: - QTcpServer* m_server; -}; - -#endif diff --git a/src/qtestlib/wince/cetcpsyncserver/main.cpp b/src/qtestlib/wince/cetcpsyncserver/main.cpp deleted file mode 100644 index 77994cc8b..000000000 --- a/src/qtestlib/wince/cetcpsyncserver/main.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ -#include "connectionmanager.h" - -#include <QtCore> -#include <QtNetwork> - -void messageOutput(QtMsgType type, const QMessageLogContext &, const QString &msg) -{ - switch(type) { - case QtDebugMsg: fprintf(stderr, "Debug: %s\n", qPrintable(msg)); break; - case QtWarningMsg: fprintf(stderr, "Warning: %s\n", qPrintable(msg)); break; - default: fprintf(stderr, "Some Msg: %s\n", qPrintable(msg)); break; - } -} - -int main(int argc, char **argv) -{ - qInstallMessageHandler(messageOutput); - - QCoreApplication app(argc, argv); - ConnectionManager manager; - manager.init(); - return app.exec(); -} diff --git a/src/qtestlib/wince/cetcpsyncserver/transfer_global.h b/src/qtestlib/wince/cetcpsyncserver/transfer_global.h deleted file mode 100644 index 426c37d85..000000000 --- a/src/qtestlib/wince/cetcpsyncserver/transfer_global.h +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ -#ifndef TRANSFER_GLOBAL_H -#define TRANSFER_GLOBAL_H - -#include <QtCore/qglobal.h> -#ifdef Q_OS_WIN -#include <windows.h> -#endif - -#define SERVER_PORT 12145 - -#define MAX_NAME_LENGTH 512 -#define MAX_ARGUMENTS 10 - -// Defines for commands sent/received -#define COMMAND_CREATE_FILE "CREATEFILE" -#define COMMAND_CREATE_DIRECTORY "CREATEDIR" -#define COMMAND_COPY_FILE "COPYFILE" -#define COMMAND_COPY_DIRECTORY "COPYDIR" -#define COMMAND_DELETE_FILE "DELETEFILE" -#define COMMAND_DELETE_DIRECTORY "DELETEDIR" -#define COMMAND_EXECUTE "EXECUTE" -#define COMMAND_QUIT_SERVER "QUIT" -#define COMMAND_FILE_TIME "FILETIME" -#define COMMAND_TIME_STAMP "TIMESTAMP" - -// Report back commands -#define COMMAND_SUCCESS "SUCCESS" -#define COMMAND_ERROR "ERROR" - -// Defines for commands that send data back to requester -#define COMMAND_READ_FILE "READFILE" -#define COMMAND_READ_DIRECTORY "READDIR" - -#include <QtCore/qglobal.h> -// Option-Structures for commands - -struct CreateFileOptions -{ - char fileName[MAX_NAME_LENGTH]; -#ifdef Q_OS_WIN - FILETIME fileTime; - DWORD fileAttributes; -#endif - int fileSize; - bool overwriteExisting; -}; - -struct CreateDirectoryOptions -{ - char dirName[MAX_NAME_LENGTH]; - bool recursively; // in case of \foo\bar create \foo if it does not exist -}; - -struct CopyFileOptions -{ - char from[MAX_NAME_LENGTH]; - char to[MAX_NAME_LENGTH]; - bool overwriteExisting; -}; - -struct CopyDirectoryOptions -{ - char from[MAX_NAME_LENGTH]; - char to[MAX_NAME_LENGTH]; - bool recursive; -}; - -struct DeleteFileOptions -{ - char fileName[MAX_NAME_LENGTH]; -}; - -struct DeleteDirectoryOptions -{ - char dirName[MAX_NAME_LENGTH]; - bool recursive; - bool failIfContentExists; -}; - -struct ExecuteOptions -{ - char appName[MAX_NAME_LENGTH]; - int argumentsCount; - bool waitForFinished; - int timeout; -}; - -struct ReadFileOptions -{ - char fileName[MAX_NAME_LENGTH]; -}; - -struct ReadFileReply -{ - qint64 fileSize; - bool fileValid; -}; - -struct ReadDirectoryOptions -{ - char dirName[MAX_NAME_LENGTH]; -}; - -struct ReadDirectoryItem -{ - char name[MAX_NAME_LENGTH]; - qint64 size; - bool isDirectory; - bool hasMore; -}; - -#define FileTimeOptions ReadFileOptions - -struct ReadDirectoryReply -{ - bool entryValid; - int itemCount; // might change during iteration -}; -#endif diff --git a/src/qtestlib/wince/cetest/activesyncconnection.cpp b/src/qtestlib/wince/cetest/activesyncconnection.cpp deleted file mode 100644 index 074013161..000000000 --- a/src/qtestlib/wince/cetest/activesyncconnection.cpp +++ /dev/null @@ -1,638 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ - -#include "activesyncconnection.h" -#include <qdir.h> -#include <qfile.h> -#include <qfileinfo> -#include <rapi.h> - -extern void debugOutput(const QString& text, int level); - -ActiveSyncConnection::ActiveSyncConnection() - : AbstractRemoteConnection() - , connected(false) -{ -} - -ActiveSyncConnection::~ActiveSyncConnection() -{ - if (isConnected()) - disconnect(); -} - -bool ActiveSyncConnection::connect(QVariantList&) -{ - if (connected) - return true; - connected = false; - RAPIINIT init; - init.cbSize = sizeof(init); - if (CeRapiInitEx(&init) != S_OK) - return connected; - - DWORD res; - res = WaitForMultipleObjects(1,&(init.heRapiInit),true, 5000); - if ((res == -1) || (res == WAIT_TIMEOUT) || (init.hrRapiInit != S_OK)) - return connected; - - connected = true; - return connected; -} - -void ActiveSyncConnection::disconnect() -{ - connected = false; - CeRapiUninit(); -} - -bool ActiveSyncConnection::isConnected() const -{ - return connected; -} - -bool ActiveSyncConnection::copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists) -{ - if (failIfExists) { - CE_FIND_DATA search; - HANDLE searchHandle = CeFindFirstFile(deviceDest.utf16(), &search); - if (searchHandle != INVALID_HANDLE_VALUE) { - CeFindClose(searchHandle); - return false; - } - } - - QFile file(localSource); - if (!file.exists()) - return false; - if (!file.open(QIODevice::ReadOnly)) { - debugOutput(QString::fromLatin1(" Could not open source file"),2); - if (file.size() == 0) { - // Create an empy file - deleteFile(deviceDest); - HANDLE deviceHandle = CeCreateFile(deviceDest.utf16(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); - if (deviceHandle != INVALID_HANDLE_VALUE) { - CeCloseHandle(deviceHandle); - return true; - } - } else { - qWarning("Could not open %s: %s", qPrintable(localSource), qPrintable(file.errorString())); - } - return false; - } - - deleteFile(deviceDest); - HANDLE deviceHandle = CeCreateFile(deviceDest.utf16(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); - if (deviceHandle == INVALID_HANDLE_VALUE) { - qWarning("Could not create %s: %s", qPrintable(deviceDest), strwinerror(CeGetLastError()).constData()); - return false; - } - - DWORD written = 0; - int currentPos = 0; - int size = file.size(); - DWORD toWrite = 0; - const int bufferSize = 65000; - QByteArray data; - data.reserve(bufferSize); - while (currentPos < size) { - data = file.read(bufferSize); - if (data.size() <= 0) { - wprintf( L"Error while reading file!\n"); - return false; - } - if (size - currentPos > bufferSize ) - toWrite = bufferSize; - else - toWrite = size - currentPos; - if (toWrite == 0) - break; - if (!CeWriteFile(deviceHandle, data.data() , toWrite, &written, NULL)) { - qWarning("Could not write to %s: %s", qPrintable(deviceDest), strwinerror(CeGetLastError()).constData()); - return false; - } - currentPos += written; - data.clear(); - wprintf( L"%s -> %s (%d / %d) %d %%\r", localSource.utf16() , deviceDest.utf16(), currentPos , size, (100*currentPos)/size ); - } - wprintf(L"\n"); - - // Copy FileTime for update verification - FILETIME creationTime, accessTime, writeTime; - HANDLE localHandle = CreateFile(localSource.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); - if (localHandle != INVALID_HANDLE_VALUE) { - if (GetFileTime(localHandle, &creationTime, &accessTime, &writeTime)) { - LocalFileTimeToFileTime(&writeTime, &writeTime); - if (!CeSetFileTime(deviceHandle, &writeTime, NULL, NULL)) { - debugOutput(QString::fromLatin1(" Could not write time values"), 0); - } - } - CloseHandle(localHandle); - } - CeCloseHandle(deviceHandle); - - DWORD attributes = GetFileAttributes(localSource.utf16()); - if (attributes != -1 ) - CeSetFileAttributes(deviceDest.utf16(), attributes); - return true; -} - -bool ActiveSyncConnection::copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive) -{ - QDir dir(localSource); - if (!dir.exists()) - return false; - - deleteDirectory(deviceDest, recursive); - CeCreateDirectory(deviceDest.utf16(), NULL); - foreach(QString entry, dir.entryList(QDir::AllEntries | QDir::NoDotAndDotDot)) { - QString source = localSource + "\\" + entry; - QString target = deviceDest + "\\" + entry; - QFileInfo info(source); - if (info.isDir()) { - if (recursive) { - if (!copyDirectoryToDevice(source, target, recursive)) - return false; - } - } else { - if (!copyFileToDevice(source, target)) - return false; - } - } - return true; -} - -bool ActiveSyncConnection::copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists) -{ - QFile target(localDest); - if (failIfExists && target.exists()) { - debugOutput(QString::fromLatin1(" Not allowed to overwrite file"), 2); - return false; - } - - if (target.exists()) - target.remove(); - - HANDLE deviceHandle = CeCreateFile(deviceSource.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); - if (deviceHandle == INVALID_HANDLE_VALUE) { - debugOutput(QString::fromLatin1(" Could not open file on device"), 2); - return false; - } - - DWORD fileSize = CeGetFileSize( deviceHandle, NULL ); - if (fileSize == -1) { - debugOutput(QString::fromLatin1(" Could not stat filesize of remote file"), 2); - CeCloseHandle(deviceHandle); - return false; - } - - if (!target.open(QIODevice::WriteOnly | QIODevice::Truncate)) { - debugOutput(QString::fromLatin1(" Could not open local file for writing"), 2); - CeCloseHandle(deviceHandle); - return false; - } - - int bufferSize = 65000; - char *buffer = (char*) malloc(bufferSize); - DWORD bufferRead = 0; - DWORD bufferWritten = 0; - bool readUntilEnd = false; - while(CeReadFile(deviceHandle, buffer, bufferSize, &bufferRead, NULL)) { - if (bufferRead == 0) { - readUntilEnd = true; - break; - } - target.write(buffer, bufferRead); - bufferWritten += bufferRead; - wprintf(L"%s -> %s (%d / %d) %d %%\r", deviceSource.utf16(), localDest.utf16(), bufferWritten, fileSize, (100*bufferWritten)/fileSize); - } - wprintf(L"\n"); - - if (!readUntilEnd) { - debugOutput(QString::fromLatin1(" an error occurred during copy"), 2); - return false; - } - - CeCloseHandle(deviceHandle); - return true; -} - -bool ActiveSyncConnection::copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive) -{ - if (!QDir(localDest).exists() && !QDir(localDest).mkpath(QDir(localDest).absolutePath())) { - debugOutput(QString::fromLatin1(" Could not create local path"), 2); - } - - QString searchArg = deviceSource + "\\*"; - CE_FIND_DATA data; - HANDLE searchHandle = CeFindFirstFile(searchArg.utf16(), &data); - if (searchHandle == INVALID_HANDLE_VALUE) { - // We return true because we might be in a recursive call - // where nothing is to copy and the copy process - // might still be correct - return true; - } - - do { - QString srcFile = deviceSource + "\\" + QString::fromWCharArray(data.cFileName); - QString destFile = localDest + "\\" + QString::fromWCharArray(data.cFileName); - if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - if (recursive && !copyDirectoryFromDevice(srcFile, destFile, recursive)) { - wprintf(L"Copy of subdirectory(%s) failed\n", srcFile.utf16()); - return false; - } - } else { - copyFileFromDevice(srcFile, destFile, false); - } - } while(CeFindNextFile(searchHandle, &data)); - CeFindClose(searchHandle); - return true; -} - -bool ActiveSyncConnection::copyFile(const QString &srcFile, const QString &destFile, bool failIfExists) -{ - return CeCopyFile(QDir::toNativeSeparators(srcFile).utf16(), - QDir::toNativeSeparators(destFile).utf16(), failIfExists); -} - -bool ActiveSyncConnection::copyDirectory(const QString &srcDirectory, const QString &destDirectory, - bool recursive) -{ - CeCreateDirectory(destDirectory.utf16(), NULL); - QString searchArg = srcDirectory + "\\*"; - CE_FIND_DATA data; - HANDLE searchHandle = CeFindFirstFile(searchArg.utf16(), &data); - if (searchHandle == INVALID_HANDLE_VALUE) { - // We return true because we might be in a recursive call - // where nothing is to copy and the copy process - // might still be correct - return true; - } - - do { - QString srcFile = srcDirectory + "\\" + QString::fromWCharArray(data.cFileName); - QString destFile = destDirectory + "\\" + QString::fromWCharArray(data.cFileName); - if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - if (recursive && !copyDirectory(srcFile, destFile, recursive)) { - wprintf(L"Copy of subdirectory(%s) failed\n", srcFile.utf16()); - return false; - } - } else { - debugOutput(QString::fromLatin1("Copy %1 -> %2\n").arg(srcFile).arg(destFile), 0); - CeCopyFile(srcFile.utf16(), destFile.utf16(), false); - } - } while(CeFindNextFile(searchHandle, &data)); - CeFindClose(searchHandle); - return true; -} - -bool ActiveSyncConnection::deleteFile(const QString &fileName) -{ - CeSetFileAttributes(fileName.utf16(), FILE_ATTRIBUTE_NORMAL); - return CeDeleteFile(fileName.utf16()); -} - -bool ActiveSyncConnection::deleteDirectory(const QString &directory, bool recursive, bool failIfContentExists) -{ - HANDLE hFind; - CE_FIND_DATA FindFileData; - QString FileName = directory + "\\*"; - hFind = CeFindFirstFile(FileName.utf16(), &FindFileData); - if( hFind == INVALID_HANDLE_VALUE ) - return CeRemoveDirectory(directory.utf16()); - - if (failIfContentExists) - return false; - - do { - QString FileName = directory + "\\" + QString::fromWCharArray(FindFileData.cFileName); - if((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - if (recursive) - if (!deleteDirectory(FileName, recursive, failIfContentExists)) - return false; - } else { - if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) - CeSetFileAttributes(FileName.utf16(), FILE_ATTRIBUTE_NORMAL); - if( !CeDeleteFile(FileName.utf16()) ) - break; - } - } while(CeFindNextFile(hFind,&FindFileData)); - CeFindClose(hFind); - - return CeRemoveDirectory(directory.utf16()); -} - -bool ActiveSyncConnection::execute(QString program, QString arguments, int timeout, int *returnValue) -{ - if (!isConnected()) { - qWarning("Cannot execute, connect to device first!"); - return false; - } - - PROCESS_INFORMATION* pid = new PROCESS_INFORMATION; - bool result = false; - if (timeout != 0) { - // If we want to wait, we have to use CeRapiInvoke, as CeCreateProcess has no way to wait - // until the process ends. The lib must have been build and also deployed already. - if (!isConnected() && !connect()) - return false; - - QString dllLocation = "\\Windows\\QtRemote.dll"; - QString functionName = "qRemoteLaunch"; - - DWORD outputSize; - BYTE* output; - IRAPIStream *stream; - int returned = 0; - DWORD error = 0; - HRESULT res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0); - if (S_OK != res) { - DWORD ce_error = CeGetLastError(); - if (S_OK != ce_error) { - qWarning("Error invoking %s on %s: %s", qPrintable(functionName), - qPrintable(dllLocation), strwinerror(ce_error).constData()); - } else { - qWarning("Error: %s on %s unexpectedly returned %d", qPrintable(functionName), - qPrintable(dllLocation), res); - } - } else { - DWORD written; - int strSize = program.length(); - if (S_OK != stream->Write(&strSize, sizeof(strSize), &written)) { - qWarning(" Could not write appSize to process"); - return false; - } - if (S_OK != stream->Write(program.utf16(), program.length()*sizeof(wchar_t), &written)) { - qWarning(" Could not write appName to process"); - return false; - } - strSize = arguments.length(); - if (S_OK != stream->Write(&strSize, sizeof(strSize), &written)) { - qWarning(" Could not write argumentSize to process"); - return false; - } - if (S_OK != stream->Write(arguments.utf16(), arguments.length()*sizeof(wchar_t), &written)) { - qWarning(" Could not write arguments to process"); - return false; - } - if (S_OK != stream->Write(&timeout, sizeof(timeout), &written)) { - qWarning(" Could not write waiting option to process"); - return false; - } - - if (S_OK != stream->Read(&returned, sizeof(returned), &written)) { - qWarning(" Could not access return value of process"); - } - if (S_OK != stream->Read(&error, sizeof(error), &written)) { - qWarning(" Could not access error code"); - } - - if (error) { - qWarning("Error on target: %s", strwinerror(error).constData()); - result = false; - } - else { - result = true; - } - } - - if (returnValue) - *returnValue = returned; - } else { - // We do not need to invoke another lib etc, if we are not interested in results anyway... - result = CeCreateProcess(program.utf16(), arguments.utf16(), 0, 0, false, 0, 0, 0, 0, pid); - } - return result; -} - -bool ActiveSyncConnection::setDeviceAwake(bool activate, int *returnValue) -{ - if (!isConnected()) { - qWarning("Cannot execute, connect to device first!"); - return false; - } - bool result = false; - - // If we want to wait, we have to use CeRapiInvoke, as CeCreateProcess has no way to wait - // until the process ends. The lib must have been build and also deployed already. - if (!isConnected() && !connect()) - return false; - - HRESULT res = S_OK; - - //SYSTEM_POWER_STATUS_EX systemPowerState; - - //res = CeGetSystemPowerStatusEx(&systemPowerState, true); - - QString dllLocation = "\\Windows\\QtRemote.dll"; - QString functionName = "qRemoteToggleUnattendedPowerMode"; - - DWORD outputSize; - BYTE* output; - IRAPIStream *stream; - int returned = 0; - int toggle = int(activate); - - res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0); - if (S_OK != res) { - DWORD ce_error = CeGetLastError(); - if (S_OK != ce_error) { - qWarning("Error invoking %s on %s: %s", qPrintable(functionName), - qPrintable(dllLocation), strwinerror(ce_error).constData()); - } else { - qWarning("Error: %s on %s unexpectedly returned %d", qPrintable(functionName), - qPrintable(dllLocation), res); - } - } else { - DWORD written; - - if (S_OK != stream->Write(&toggle, sizeof(toggle), &written)) { - qWarning(" Could not write toggle option to process"); - return false; - } - - if (S_OK != stream->Read(&returned, sizeof(returned), &written)) { - qWarning(" Could not access return value of process"); - } - else - result = true; - } - - if (returnValue) - *returnValue = returned; - - return result; -} - -bool ActiveSyncConnection::resetDevice() -{ - if (!isConnected()) { - qWarning("Cannot execute, connect to device first!"); - return false; - } - - bool result = false; - if (!isConnected() && !connect()) - return false; - - QString dllLocation = "\\Windows\\QtRemote.dll"; - QString functionName = "qRemoteSoftReset"; - - DWORD outputSize; - BYTE* output; - IRAPIStream *stream; - - int returned = 0; - - HRESULT res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0); - if (S_OK != res) { - DWORD ce_error = CeGetLastError(); - if (S_OK != ce_error) { - qWarning("Error invoking %s on %s: %s", qPrintable(functionName), - qPrintable(dllLocation), strwinerror(ce_error).constData()); - } else { - qWarning("Error: %s on %s unexpectedly returned %d", qPrintable(functionName), - qPrintable(dllLocation), res); - } - } else { - result = true; - } - return result; -} - -bool ActiveSyncConnection::toggleDevicePower(int *returnValue) -{ - if (!isConnected()) { - qWarning("Cannot execute, connect to device first!"); - return false; - } - - bool result = false; - if (!isConnected() && !connect()) - return false; - - QString dllLocation = "\\Windows\\QtRemote.dll"; - QString functionName = "qRemotePowerButton"; - - DWORD outputSize; - BYTE* output; - IRAPIStream *stream; - int returned = 0; - - HRESULT res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0); - if (S_OK != res) { - DWORD ce_error = CeGetLastError(); - if (S_OK != ce_error) { - qWarning("Error invoking %s on %s: %s", qPrintable(functionName), - qPrintable(dllLocation), strwinerror(ce_error).constData()); - } else { - qWarning("Error: %s on %s unexpectedly returned %d", qPrintable(functionName), - qPrintable(dllLocation), res); - } - } else { - DWORD written; - if (S_OK != stream->Read(&returned, sizeof(returned), &written)) { - qWarning(" Could not access return value of process"); - } - else { - result = true; - } - } - - if (returnValue) - *returnValue = returned; - return result; -} - -bool ActiveSyncConnection::createDirectory(const QString &path, bool deleteBefore) -{ - if (deleteBefore) - deleteDirectory(path); - QStringList separated = path.split(QLatin1Char('\\')); - QString current = QLatin1String("\\"); - bool result; - for (int i=1; i < separated.size(); ++i) { - current += separated.at(i); - result = CeCreateDirectory(current.utf16(), NULL); - current += QLatin1String("\\"); - } - return result; -} - -bool ActiveSyncConnection::timeStampForLocalFileTime(FILETIME* fTime) const -{ - QString tmpFile = QString::fromLatin1("\\qt_tmp_ftime_convert"); - HANDLE remoteHandle = CeCreateFile(tmpFile.utf16(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); - if (remoteHandle == INVALID_HANDLE_VALUE) - return false; - - LocalFileTimeToFileTime(fTime, fTime); - - if (!CeSetFileTime(remoteHandle, fTime, NULL, NULL)) { - CeCloseHandle(remoteHandle); - return false; - } - - CeCloseHandle(remoteHandle); - remoteHandle = CeCreateFile(tmpFile.utf16(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); - if (remoteHandle == INVALID_HANDLE_VALUE) - return false; - if (!CeGetFileTime(remoteHandle, fTime, NULL, NULL)) { - CeCloseHandle(remoteHandle); - return false; - } - - CeCloseHandle(remoteHandle); - CeDeleteFile(tmpFile.utf16()); - return true; -} - -bool ActiveSyncConnection::fileCreationTime(const QString &fileName, FILETIME* deviceCreationTime) const -{ - HANDLE deviceHandle = CeCreateFile(fileName.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); - if (deviceHandle == INVALID_HANDLE_VALUE) - return false; - - bool result = true; - if (!CeGetFileTime(deviceHandle, deviceCreationTime, NULL, NULL)) - result = false; - - CeCloseHandle(deviceHandle); - return result; -} diff --git a/src/qtestlib/wince/cetest/activesyncconnection.h b/src/qtestlib/wince/cetest/activesyncconnection.h deleted file mode 100644 index 154a592dd..000000000 --- a/src/qtestlib/wince/cetest/activesyncconnection.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ - -#ifndef ACTIVESYNC_REMOTECONNECTION_H -#define ACTIVESYNC_REMOTECONNECTION_H - -#include "remoteconnection.h" - -#if defined(Q_OS_WIN32) -#define REMOTELIBNAME "remotecommands" -#endif - -class ActiveSyncConnection : public AbstractRemoteConnection -{ -public: - ActiveSyncConnection(); - virtual ~ActiveSyncConnection(); - - bool connect(QVariantList &list = QVariantList()); - void disconnect(); - bool isConnected() const; - - // These functions are designed for transfer between desktop and device - // Caution: deviceDest path has to be device specific (eg. no drive letters for CE) - bool copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists = false); - bool copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive = true); - bool copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists = false); - bool copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive = true); - - bool timeStampForLocalFileTime(FILETIME*) const; - bool fileCreationTime(const QString &fileName, FILETIME*) const; - - // These functions only work on files existing on the device - bool copyFile(const QString&, const QString&, bool failIfExists = false); - bool copyDirectory(const QString&, const QString&, bool recursive = true); - bool deleteFile(const QString&); - bool deleteDirectory(const QString&, bool recursive = true, bool failIfContentExists = false); - bool moveFile(const QString&, const QString&, bool FailIfExists = false); - bool moveDirectory(const QString&, const QString&, bool recursive = true); - - bool createDirectory(const QString&, bool deleteBefore=false); - - bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL); - bool resetDevice(); - bool toggleDevicePower(int *returnValue = NULL); - bool setDeviceAwake(bool activate, int *returnValue = NULL); -private: - bool connected; -}; - -#endif diff --git a/src/qtestlib/wince/cetest/bootstrapped.pri b/src/qtestlib/wince/cetest/bootstrapped.pri deleted file mode 100644 index 9affc0536..000000000 --- a/src/qtestlib/wince/cetest/bootstrapped.pri +++ /dev/null @@ -1,47 +0,0 @@ -# Bootstrapped Input -SOURCES += \ - $$QT.core.sources/tools/qstring.cpp \ - $$QT.core.sources/tools/qstringlist.cpp \ - $$QT.core.sources/io/qfile.cpp \ - $$QT.core.sources/io/qdir.cpp \ - $$QT.core.sources/io/qfilesystementry.cpp \ - $$QT.core.sources/io/qfilesystemengine.cpp \ - $$QT.core.sources/io/qfilesystemengine_win.cpp \ - $$QT.core.sources/io/qfilesystemiterator_win.cpp \ - $$QT.core.sources/io/qfsfileengine.cpp \ - $$QT.core.sources/io/qabstractfileengine.cpp \ - $$QT.core.sources/io/qfsfileengine_win.cpp \ - $$QT.core.sources/io/qfsfileengine_iterator.cpp \ - $$QT.core.sources/io/qfileinfo.cpp \ - $$QT.core.sources/io/qtemporaryfile.cpp \ - $$QT.core.sources/io/qdiriterator.cpp \ - $$QT.core.sources/io/qiodevice.cpp \ - $$QT.core.sources/io/qbuffer.cpp \ - $$QT.core.sources/io/qtextstream.cpp \ - $$QT.core.sources/io/qurl.cpp \ - $$QT.core.sources/io/qsettings.cpp \ - $$QT.core.sources/io/qsettings_win.cpp \ - $$QT.core.sources/tools/qdatetime.cpp \ - $$QT.core.sources/tools/qlocale.cpp \ - $$QT.core.sources/tools/qbytearray.cpp \ - $$QT.core.sources/tools/qbytearraymatcher.cpp \ - $$QT.core.sources/tools/qvector.cpp \ - $$QT.core.sources/tools/qvsnprintf.cpp \ - $$QT.core.sources/tools/qlist.cpp \ - $$QT.core.sources/tools/qhash.cpp \ - $$QT.core.sources/tools/qlocale_tools.cpp \ - $$QT.core.sources/global/qglobal.cpp \ - $$shadowed($$QT.core.sources)/global/qconfig.cpp \ - $$QT.core.sources/global/qmalloc.cpp \ - $$QT.core.sources/global/qnumeric.cpp \ - $$QT.core.sources/global/qlibraryinfo.cpp \ - $$QT.core.sources/tools/qregexp.cpp \ - $$QT.core.sources/tools/qmap.cpp \ - $$QT.core.sources/tools/qbitarray.cpp \ - $$QT.core.sources/kernel/qmetatype.cpp \ - $$QT.core.sources/kernel/qvariant.cpp \ - $$QT.core.sources/kernel/qsystemerror.cpp \ - $$QT.core.sources/plugin/qsystemlibrary.cpp \ - $$QT.core.sources/codecs/qutfcodec.cpp \ - $$QT.core.sources/xml/qxmlstream.cpp \ - $$QT.core.sources/xml/qxmlutils.cpp diff --git a/src/qtestlib/wince/cetest/cetcpsyncconnection.cpp b/src/qtestlib/wince/cetest/cetcpsyncconnection.cpp deleted file mode 100644 index e85231f8b..000000000 --- a/src/qtestlib/wince/cetest/cetcpsyncconnection.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ - -#include "CeTcpSyncConnection.h" -#include <qdir.h> -#include <qfile.h> -#include <qfileinfo> - -static const QString ceTcpSyncProgram = "cetcpsync"; -extern void debugOutput(const QString& text, int level); - -CeTcpSyncConnection::CeTcpSyncConnection() - : AbstractRemoteConnection() - , connected(false) -{ -} - -CeTcpSyncConnection::~CeTcpSyncConnection() -{ - if (isConnected()) - disconnect(); -} - -bool CeTcpSyncConnection::connect(QVariantList&) -{ - // We connect with each command, so this is always true - // The command itself will fail then - const QString cmd = ceTcpSyncProgram + " noop"; - if (system(qPrintable(cmd)) != 0) - return false; - connected = true; - return true; -} - -void CeTcpSyncConnection::disconnect() -{ - connected = false; -} - -bool CeTcpSyncConnection::isConnected() const -{ - return connected; -} - -inline QString boolToString(bool b) -{ - return b ? "true" : "false"; -} - -static bool fileTimeFromString(FILETIME& ft, const QString& str) -{ - int idx = str.indexOf("*"); - if (idx <= 0) - return false; - bool ok; - ft.dwLowDateTime = str.left(idx).toULong(&ok); - if (!ok) - return false; - ft.dwHighDateTime = str.mid(idx+1).toULong(&ok); - return ok; -} - -static QString fileTimeToString(FILETIME& ft) -{ - return QString::number(ft.dwLowDateTime) + "*" + QString::number(ft.dwHighDateTime); -} - -bool CeTcpSyncConnection::copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists) -{ - QString cmd = ceTcpSyncProgram + " copyFileToDevice \"" + localSource + "\" \"" + deviceDest + "\" " + boolToString(failIfExists); - return system(qPrintable(cmd)) == 0; -} - -bool CeTcpSyncConnection::copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive) -{ - QString cmd = ceTcpSyncProgram + " copyDirectoryToDevice \"" + localSource + "\" \"" + deviceDest + "\" " + boolToString(recursive); - return system(qPrintable(cmd)) == 0; -} - -bool CeTcpSyncConnection::copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists) -{ - QString cmd = ceTcpSyncProgram + " copyFileFromDevice \"" + deviceSource + "\" \"" + localDest + "\" " + boolToString(failIfExists); - return system(qPrintable(cmd)) == 0; -} - -bool CeTcpSyncConnection::copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive) -{ - QString cmd = ceTcpSyncProgram + " copyDirectoryFromDevice \"" + deviceSource + "\" \"" + localDest + "\" " + boolToString(recursive); - return system(qPrintable(cmd)) == 0; -} - -bool CeTcpSyncConnection::copyFile(const QString &srcFile, const QString &destFile, bool failIfExists) -{ - QString cmd = ceTcpSyncProgram + " copyFile \"" + srcFile + "\" \"" + destFile + "\" " + boolToString(failIfExists); - return system(qPrintable(cmd)) == 0; -} - -bool CeTcpSyncConnection::copyDirectory(const QString &srcDirectory, const QString &destDirectory, - bool recursive) -{ - QString cmd = ceTcpSyncProgram + " copyDirectory \"" + srcDirectory + "\" \"" + destDirectory + "\" " + boolToString(recursive); - return system(qPrintable(cmd)) == 0; -} - -bool CeTcpSyncConnection::deleteFile(const QString &fileName) -{ - QString cmd = ceTcpSyncProgram + " deleteFile \"" + fileName + "\""; - return system(qPrintable(cmd)) == 0; -} - -bool CeTcpSyncConnection::deleteDirectory(const QString &directory, bool recursive, bool failIfContentExists) -{ - QString cmd = ceTcpSyncProgram + " deleteDirectory \"" + directory + "\" " + boolToString(recursive) + " " + boolToString(failIfContentExists); - return system(qPrintable(cmd)) == 0; -} - -bool CeTcpSyncConnection::execute(QString program, QString arguments, int timeout, int *returnValue) -{ - QString cmd = ceTcpSyncProgram + " execute \"" + program + "\" \"" + arguments + "\" " + QString::number(timeout); - int exitCode = system(qPrintable(cmd)); - if (returnValue) - *returnValue = exitCode; - return true; -} - -bool CeTcpSyncConnection::createDirectory(const QString &path, bool deleteBefore) -{ - QString cmd = ceTcpSyncProgram + " createDirectory \"" + path + "\" " + boolToString(deleteBefore); - return system(qPrintable(cmd)) == 0; -} - -bool CeTcpSyncConnection::timeStampForLocalFileTime(FILETIME* fTime) const -{ - QString cmd = ceTcpSyncProgram + " timeStampForLocalFileTime " + fileTimeToString(*fTime) + " >qt_cetcpsyncdata.txt"; - if (system(qPrintable(cmd)) != 0) - return false; - - QFile file("qt_cetcpsyncdata.txt"); - if (!file.open(QIODevice::ReadOnly)) - return false; - - bool result = fileTimeFromString(*fTime, file.readLine()); - file.close(); - file.remove(); - return result; -} - -bool CeTcpSyncConnection::fileCreationTime(const QString &fileName, FILETIME* deviceCreationTime) const -{ - QString cmd = ceTcpSyncProgram + " fileCreationTime \"" + fileName + "\" >qt_cetcpsyncdata.txt"; - if (system(qPrintable(cmd)) != 0) - return false; - - QFile file("qt_cetcpsyncdata.txt"); - if (!file.open(QIODevice::ReadOnly)) - return false; - - bool result = fileTimeFromString(*deviceCreationTime, file.readLine()); - file.close(); - file.remove(); - return result; -} - -bool CeTcpSyncConnection::resetDevice() -{ - qWarning("CeTcpSyncConnection::resetDevice not implemented"); - return false; -} - -bool CeTcpSyncConnection::toggleDevicePower(int *returnValue) -{ - Q_UNUSED(returnValue); - qWarning("CeTcpSyncConnection::toggleDevicePower not implemented"); - return false; -} - -bool CeTcpSyncConnection::setDeviceAwake(bool activate, int *returnValue) -{ - Q_UNUSED(activate); - Q_UNUSED(returnValue); - qWarning("CeTcpSyncConnection::setDeviceAwake not implemented"); - return false; -} diff --git a/src/qtestlib/wince/cetest/cetcpsyncconnection.h b/src/qtestlib/wince/cetest/cetcpsyncconnection.h deleted file mode 100644 index abf55ac9a..000000000 --- a/src/qtestlib/wince/cetest/cetcpsyncconnection.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ - -#ifndef CETCPSYNC_REMOTECONNECTION_H -#define CETCPSYNC_REMOTECONNECTION_H - -#include "remoteconnection.h" - -class CeTcpSyncConnection : public AbstractRemoteConnection -{ -public: - CeTcpSyncConnection(); - virtual ~CeTcpSyncConnection(); - - bool connect(QVariantList &list = QVariantList()); - void disconnect(); - bool isConnected() const; - - // These functions are designed for transfer between desktop and device - // Caution: deviceDest path has to be device specific (eg. no drive letters for CE) - bool copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists = false); - bool copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive = true); - bool copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists = false); - bool copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive = true); - - bool timeStampForLocalFileTime(FILETIME*) const; - bool fileCreationTime(const QString &fileName, FILETIME*) const; - - // These functions only work on files existing on the device - bool copyFile(const QString&, const QString&, bool failIfExists = false); - bool copyDirectory(const QString&, const QString&, bool recursive = true); - bool deleteFile(const QString&); - bool deleteDirectory(const QString&, bool recursive = true, bool failIfContentExists = false); - bool moveFile(const QString&, const QString&, bool FailIfExists = false); - bool moveDirectory(const QString&, const QString&, bool recursive = true); - - bool createDirectory(const QString&, bool deleteBefore=false); - - bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL); - bool resetDevice(); - bool toggleDevicePower(int *returnValue = NULL); - bool setDeviceAwake(bool activate, int *returnValue = NULL); -private: - bool connected; -}; - -#endif diff --git a/src/qtestlib/wince/cetest/cetest.pro b/src/qtestlib/wince/cetest/cetest.pro deleted file mode 100644 index e7aa7efe3..000000000 --- a/src/qtestlib/wince/cetest/cetest.pro +++ /dev/null @@ -1,44 +0,0 @@ -CONFIG += console no_batch -CONFIG -= qt - -DEFINES += QT_BUILD_QMAKE QT_BOOTSTRAPPED QT_NO_CODECS QT_LITE_UNICODE QT_NO_LIBRARY \ - QT_NO_STL QT_NO_COMPRESS QT_NO_DATASTREAM \ - QT_NO_TEXTCODEC QT_NO_UNICODETABLES QT_NO_THREAD \ - QT_NO_SYSTEMLOCALE QT_NO_GEOM_VARIANT \ - QT_NODLL QT_NO_QOBJECT - -INCLUDEPATH = \ - $$QT.core.sources/../../tools/qtestlib/ce/cetest \ - $$QT.core.sources/../../qmake \ - $$QT.core.sources/../../tools/shared \ - $$QT.core.includes - -VPATH += $$QT.core.sources/../../tools/shared - -HEADERS += \ - remoteconnection.h \ - deployment.h - -SOURCES += \ - remoteconnection.cpp \ - deployment.cpp \ - main.cpp - -LIBS += ole32.lib advapi32.lib - -isEmpty(QT_CE_RAPI_INC) { - DEFINES += QT_CETEST_NO_ACTIVESYNC - HEADERS += cetcpsyncconnection.h - SOURCES += cetcpsyncconnection.cpp -} else { - HEADERS += activesyncconnection.h - SOURCES += activesyncconnection.cpp - LIBS += rapi.lib - INCLUDEPATH += $$QT_CE_RAPI_INC - LIBS += -L$$QT_CE_RAPI_LIB -} - -include(qmake_include.pri) -include(bootstrapped.pri) - -load(qt_app) diff --git a/src/qtestlib/wince/cetest/deployment.cpp b/src/qtestlib/wince/cetest/deployment.cpp deleted file mode 100644 index af8a96594..000000000 --- a/src/qtestlib/wince/cetest/deployment.cpp +++ /dev/null @@ -1,291 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ - -#include "deployment.h" -#include "remoteconnection.h" -#include <option.h> -#include <qdir.h> -#include <qfile.h> -#include <qstring.h> - -extern void debugOutput(const QString& text, int level); - -bool DeploymentHandler::deviceCopy(const DeploymentList &deploymentList) -{ - for (int i=0; i<deploymentList.size(); ++i) { - CopyItem item = deploymentList.at(i); - m_connection->createDirectory(item.to.left(item.to.lastIndexOf(QLatin1Char('\\')))); - if (!m_connection->copyFileToDevice(item.from , item.to)) { - debugOutput(QString::fromLatin1("Error while copy: %1 -> %2").arg(item.from).arg(item.to),0); - return false; - } - } - return true; -} - -bool DeploymentHandler::deviceDeploy(const DeploymentList &deploymentList) -{ - DeploymentList copyList; - for (int i=0; i<deploymentList.size(); ++i) { -#if defined(Q_OS_WIN) - HANDLE localHandle = CreateFile(deploymentList.at(i).from.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); - if (localHandle == INVALID_HANDLE_VALUE) { - copyList.append(deploymentList.at(i)); - continue; - } - FILETIME localCreationTime; - if (!GetFileTime(localHandle, NULL, NULL, &localCreationTime) || !m_connection->timeStampForLocalFileTime(&localCreationTime)) { - copyList.append(deploymentList.at(i)); - CloseHandle(localHandle); - continue; - } - CloseHandle(localHandle); - - FILETIME deviceCreationTime; - if (!m_connection->fileCreationTime(deploymentList.at(i).to , &deviceCreationTime)) { - copyList.append(deploymentList.at(i)); - continue; - } - - int res = CompareFileTime(&localCreationTime, &deviceCreationTime); - if (res != 0) - copyList.append(deploymentList.at(i)); - else - debugOutput(QString::fromLatin1("Skipping File %1, already latest version").arg(deploymentList.at(i).from),0); -#else - copyList.append(deploymentList.at(i)); -#endif - } - return deviceCopy(copyList); -} - -void DeploymentHandler::cleanup(const DeploymentList &deploymentList) -{ - for (int i=0; i<deploymentList.size(); ++i) { - m_connection->deleteFile(deploymentList.at(i).to); -#ifdef Q_OS_WIN - QString path = deploymentList.at(i).to; - int pos; - while ( (pos = path.lastIndexOf(QLatin1Char('\\'))) > 0) { - path = path.left(pos); - if (!m_connection->deleteDirectory(path, false, true)) - break; - } -#endif - } -} - -void DeploymentHandler::initQtDeploy(QMakeProject *project, DeploymentList &deploymentList, const QString &testPath) -{ - QString targetPath = project->values("deploy.path").join(" "); - if (targetPath.isEmpty()) - targetPath = testPath; - if (targetPath.endsWith("/") || targetPath.endsWith("\\")) - targetPath = targetPath.mid(0,targetPath.size()-1); - - // Only deploy Qt libs for shared build - if (!project->values("QMAKE_QT_DLL").isEmpty() && !project->values("QMAKE_LIBDIR").isEmpty()) { - QStringList libs = project->values("LIBS"); - QStringList qtLibs; - QStringList libPaths; - foreach (QString item, libs) { - - if (item.startsWith("-L")) { - // -L -> a directory containing DLLs - libPaths << item.mid(2); - continue; - } - - QStringList libCandidates; - - if (item.startsWith("-l")) { - // -l -> a library located within one of the standard library paths - QString lib = item.mid(2); - - // Check if it's a Qt library first, then check in all paths given with -L. - // Note Qt libraries get a `4' appended to them, others don't. - libCandidates << project->values("QMAKE_LIBDIR").at(0) + QDir::separator() + lib + QLatin1String("4.dll"); - foreach (QString const& libPath, libPaths) { - libCandidates << libPath + QDir::separator() + lib + QLatin1String(".dll"); - } - } else { - libCandidates << item.replace(".lib",".dll"); - } - - foreach (QString const& file, libCandidates) { - QFileInfo info(file); - if (info.exists()) { - qtLibs += info.dir().absoluteFilePath(info.fileName()); - break; - } - } - } - for (QStringList::ConstIterator it = qtLibs.constBegin(); it != qtLibs.constEnd(); ++it) { - QString dllName = *it; - QFileInfo info(dllName); - if (!info.exists()) - continue; - deploymentList.append(CopyItem(Option::fixPathToLocalOS(info.absoluteFilePath()) , - Option::fixPathToLocalOS(targetPath + "/" + info.fileName()))); - } - } - -#ifndef QT_CETEST_NO_ACTIVESYNC - // QtRemote deployment. We always deploy to \Windows - if (!project->values("QMAKE_LIBDIR").isEmpty()) { - QString remoteLibName = QLatin1String("QtRemote.dll"); - QString remoteLib = Option::fixPathToLocalOS(project->values("QMAKE_LIBDIR").at(0) + QDir::separator() + remoteLibName); - if (QFile::exists(remoteLib)) - deploymentList.append(CopyItem(remoteLib, QString::fromLatin1("\\Windows\\") + remoteLibName)); - else - debugOutput(QString::fromLatin1("Could not find QtRemote. Might not be able to launch target executable"),0); - } -#endif - - // C-runtime deployment - QString runtime = project->values("QT_CE_C_RUNTIME").join(QLatin1String(" ")); - debugOutput(QString::fromLatin1("Runtime:%1").arg(runtime), 2); - if (!runtime.isEmpty() && (runtime != QLatin1String("no"))) { - QString runtimeVersion = QLatin1String("msvcr"); - const QString mkspec = project->values("QMAKESPEC").first(); - if (mkspec.endsWith("2008")) - runtimeVersion.append("90"); - else - runtimeVersion.append("80"); - if (project->isActiveConfig("debug")) - runtimeVersion.append("d"); - runtimeVersion.append(".dll"); - - if (runtime == "yes") { - // Auto-find C-runtime - QString vcInstallDir = qgetenv("VCINSTALLDIR"); - if (!vcInstallDir.isEmpty()) { - vcInstallDir += "\\ce\\dll\\"; - vcInstallDir += project->values("CE_ARCH").join(QLatin1String(" ")); - if (!QFileInfo(vcInstallDir + QDir::separator() + runtimeVersion).exists()) - runtime.clear(); - else - runtime = vcInstallDir; - } - } - - if (!runtime.isEmpty()) { - deploymentList.append(CopyItem(Option::fixPathToLocalOS(runtime + "/" + runtimeVersion ) , - Option::fixPathToLocalOS(targetPath + "/" + runtimeVersion))); - } - } -} - -void DeploymentHandler::initProjectDeploy(QMakeProject* project, DeploymentList &deploymentList, const QString &testPath) -{ - QString targetPath = project->values("deploy.path").join(" "); - if (targetPath.isEmpty()) - targetPath = testPath; - if (targetPath.endsWith("/") || targetPath.endsWith("\\")) - targetPath = targetPath.mid(0,targetPath.size()-1); - - QStringList& list = project->values("DEPLOYMENT"); - if (list.isEmpty()) - return; - - for (int it = 0; it < list.size(); ++it) { - QString argSource = list.at(it); - QString argPath = list.at(it) + QString(".path"); - if ((project->values(argSource + QString(".files")).isEmpty() || project->values(argPath).isEmpty()) && list.at(it) != "deploy") { - debugOutput(QString::fromLatin1("cannot deploy \"%1\" because of missing data.").arg(list.at(it)), 0); - continue; - } - - QString addPath = project->values(argPath).join(QLatin1String(" ")); - if (addPath == QLatin1String(".")) - addPath.clear(); - if (!addPath.startsWith("/") && !addPath.startsWith(QLatin1String("\\"))) - addPath = targetPath + "/" + addPath; - - QStringList addSources = project->values(argSource + QString(".files")); - addSources.replaceInStrings(QLatin1String("/"), QLatin1String("\\")); - for(int index=0; index < addSources.size(); ++index) { - QString dirstr = qmake_getpwd(); - QString filestr = Option::fixPathToLocalOS(addSources.at(index), false, false); - int slsh = filestr.lastIndexOf(Option::dir_sep); - if(slsh != -1) { - dirstr = filestr.left(slsh+1); - filestr = filestr.right(filestr.length() - slsh - 1); - } - if(dirstr.right(Option::dir_sep.length()) != Option::dir_sep) - dirstr += Option::dir_sep; - QFileInfo info(dirstr + filestr); - - static int addQMakeDeployCounter = 0; - QStringList entryList = info.absoluteDir().entryList(QStringList() << info.fileName()); - if (entryList.size() > 1) { - foreach(QString s, entryList) { - // We do not include directories when using wildcards - QFileInfo wildInfo(info.absolutePath() + "/" + s); - if (wildInfo.isDir()) { - continue; - } - QString appendedQmakeDeploy = QString::fromLatin1("_q_make_additional_deploy_%1").arg(addQMakeDeployCounter++); - project->parse(appendedQmakeDeploy + QLatin1String(".files = \"") + wildInfo.absoluteFilePath()); - project->parse(appendedQmakeDeploy + QLatin1String(".path = \"") + addPath); - list.append(appendedQmakeDeploy); - } - continue; - } - - if (info.isDir()) { - QDir additionalDir(dirstr + filestr); - QStringList additionalEntries = additionalDir.entryList(QDir::NoDotAndDotDot | QDir::AllEntries | QDir::NoSymLinks); - foreach(QString item, additionalEntries) { - QString appendedDeploy = QString::fromLatin1("_q_make_additional_deploy_%1").arg(addQMakeDeployCounter++); - project->parse(appendedDeploy + QLatin1String(".files = \"") + Option::fixPathToLocalOS(additionalDir.absoluteFilePath(item)) + QLatin1String("\"")); - QString appendTargetPath = project->values(argPath).join(QLatin1String(" ")); - if (appendTargetPath == QLatin1String(".")) - appendTargetPath = filestr; - else - appendTargetPath.append(QLatin1String("\\") + filestr); - project->parse(appendedDeploy + QLatin1String(".path = ") + appendTargetPath); - list.append(appendedDeploy); - } - } else if (entryList.size() == 1) - deploymentList.append(CopyItem(Option::fixPathToLocalOS(info.absolutePath() + "/" + entryList.at(0)) , - Option::fixPathToLocalOS(addPath + "/" + entryList.at(0)))); - } - } -} diff --git a/src/qtestlib/wince/cetest/deployment.h b/src/qtestlib/wince/cetest/deployment.h deleted file mode 100644 index e18e92fab..000000000 --- a/src/qtestlib/wince/cetest/deployment.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ - -#ifndef DEPLOYMENT_INCL -#define DEPLOYMENT_INCL - -#include <qstring.h> -#include <qlist.h> -#include <project.h> - -class AbstractRemoteConnection; - -struct CopyItem -{ - CopyItem(const QString& f, const QString& t) : from(f) , to(t) { } - QString from; - QString to; -}; -typedef QList<CopyItem> DeploymentList; - -class DeploymentHandler -{ -public: - inline void setConnection(AbstractRemoteConnection*); - inline AbstractRemoteConnection* connection() const; - bool deviceCopy(const DeploymentList &deploymentList); - bool deviceDeploy(const DeploymentList &deploymentList); - void cleanup(const DeploymentList &deploymentList); - static void initProjectDeploy(QMakeProject* project, DeploymentList &deploymentList, const QString &testPath = "\\Program Files\\qt_test"); - static void initQtDeploy(QMakeProject* project, DeploymentList &deploymentList, const QString &testPath = "\\Program Files\\qt_test"); -private: - AbstractRemoteConnection* m_connection; -}; - -inline void DeploymentHandler::setConnection(AbstractRemoteConnection *connection) { m_connection = connection; } -inline AbstractRemoteConnection* DeploymentHandler::connection() const { return m_connection; } -#endif
\ No newline at end of file diff --git a/src/qtestlib/wince/cetest/main.cpp b/src/qtestlib/wince/cetest/main.cpp deleted file mode 100644 index d271a097a..000000000 --- a/src/qtestlib/wince/cetest/main.cpp +++ /dev/null @@ -1,431 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ - -#ifdef QT_CETEST_NO_ACTIVESYNC -# include "cetcpsyncconnection.h" -#else -# include "activesyncconnection.h" -#endif - -const int SLEEP_AFTER_RESET = 60000; // sleep for 1 minute -const int SLEEP_RECONNECT = 2000; // sleep for 2 seconds before trying another reconnect - -#include "deployment.h" -#include <option.h> -#include <project.h> -#include <property.h> -#include <qstringlist.h> -#include <qfileinfo.h> -#include <qdir.h> -#include <iostream> -using namespace std; - -const int debugLevel = 0; -void debugOutput(const QString& text, int level) -{ - if (level <= debugLevel) - cout << qPrintable(text) << endl; -} - -// needed for QMake sources to compile -QString project_builtin_regx() { return QString();} -static QString pwd; -QString qmake_getpwd() -{ - if(pwd.isNull()) - pwd = QDir::currentPath(); - return pwd; -} -bool qmake_setpwd(const QString &p) -{ - if(QDir::setCurrent(p)) { - pwd = QDir::currentPath(); - return true; - } - return false; -} - -namespace TestConfiguration { - QString localExecutable; - QString localQtConf; - QString remoteTestPath; - QString remoteLibraryPath; - QString remoteExecutable; - QString remoteResultFile; - - bool testDebug; - void init() - { - testDebug = true; - localQtConf = QLatin1String("no"); - remoteTestPath = QLatin1String("\\Program Files\\qt_test"); - remoteLibraryPath = remoteTestPath; - remoteResultFile = QLatin1String("\\qt_test_results.txt"); - } -} - -void usage() -{ - cout << - "QTestLib options\n" - " All valid QTestLib command-line options are accepted.\n" - " For details of QTestLib options, refer to the QTestLib Manual.\n" - "\n" - "cetest specific options\n" - " -debug : Test debug version[default]\n" - " -release : Test release version\n" - " -libpath <path> : Remote path to deploy Qt libraries to\n" - " -reset : Reset device before starting a test\n" - " -awake : Device does not go sleep mode\n" - " -qt-delete : Delete the Qt libraries after execution\n" - " -project-delete : Delete the project file(s) after execution\n" - " -delete : Delete everything deployed after execution\n" - " -conf : Specify location of qt.conf file\n" - " -f <file> : Specify project file\n" - " -cache <file> : Specify .qmake.cache file to use\n" - " -d : Increase qmake debugging \n" - " -timeout <value> : Specify a timeout value after which the test will be terminated\n" - " -1 specifies waiting forever (default)\n" - " 0 specifies starting the process detached\n" - " >0 wait <value> seconds\n" - " -help : This help\n" - "\n"; -} - -int main(int argc, char **argv) -{ - QStringList arguments; - for (int i=0; i<argc; ++i) - arguments.append(QString::fromLatin1(argv[i])); - - TestConfiguration::init(); - - QStringList launchArguments; - QString resultFile; - QString proFile; - QString cacheFile; - int timeout = -1; - bool cleanupQt = false; - bool cleanupProject = false; - bool deviceReset = false; - bool keepAwake = false; - - for (int i=1; i<arguments.size(); ++i) { - if (arguments.at(i).toLower() == QLatin1String("-help") - || arguments.at(i).toLower() == QLatin1String("--help") - || arguments.at(i).toLower() == QLatin1String("/?")) { - usage(); - return 0; - } else if (arguments.at(i).toLower() == QLatin1String("-o")) { - if (++i == arguments.size()) { - cout << "Error: No output file specified!" << endl; - return -1; - } - resultFile = arguments.at(i); - } else if (arguments.at(i).toLower() == QLatin1String("-eventdelay") - || arguments.at(i).toLower() == QLatin1String("-keydelay") - || arguments.at(i).toLower() == QLatin1String("-mousedelay") - || arguments.at(i).toLower() == QLatin1String("-maxwarnings")) { - launchArguments.append(arguments.at(i++)); - if (i == arguments.size()) { - cout << "Please specify value for:" << qPrintable(arguments.at(i-1).mid(1)) << endl; - return -1; - } - launchArguments.append(arguments.at(i)); - } else if (arguments.at(i).toLower() == QLatin1String("-debug")) { - TestConfiguration::testDebug = true; - Option::before_user_vars.append("CONFIG-=release"); - Option::before_user_vars.append("CONFIG+=debug"); - } else if (arguments.at(i).toLower() == QLatin1String("-release")) { - TestConfiguration::testDebug = false; - Option::before_user_vars.append("CONFIG-=debug"); - Option::before_user_vars.append("CONFIG+=release"); - } else if (arguments.at(i).toLower() == QLatin1String("-libpath")) { - if (++i == arguments.size()) { - cout << "Error: No library path specified!" << endl; - return -1; - } - TestConfiguration::remoteLibraryPath = arguments.at(i); - } else if (arguments.at(i).toLower() == QLatin1String("-qt-delete")) { - cleanupQt = true; - } else if (arguments.at(i).toLower() == QLatin1String("-project-delete")) { - cleanupProject = true; - } else if (arguments.at(i).toLower() == QLatin1String("-delete")) { - cleanupQt = true; - cleanupProject = true; - } else if (arguments.at(i).toLower() == QLatin1String("-reset")) { - deviceReset = true; - } else if (arguments.at(i).toLower() == QLatin1String("-awake")) { - keepAwake = true; - } else if (arguments.at(i).toLower() == QLatin1String("-conf")) { - if (++i == arguments.size()) { - cout << "Error: No qt.conf file specified!" << endl; - return -1; - } - if (!QFileInfo(arguments.at(i)).exists()) - cout << "Warning: could not find qt.conf file at:" << qPrintable(arguments.at(i)) << endl; - else - TestConfiguration::localQtConf = arguments.at(i); - } else if (arguments.at(i).toLower() == QLatin1String("-f")) { - if (++i == arguments.size()) { - cout << "Error: No output file specified!" << endl; - return -1; - } - proFile = arguments.at(i); - } else if (arguments.at(i).toLower() == QLatin1String("-cache")) { - if (++i == arguments.size()) { - cout << "Error: No cache file specified!" << endl; - return -1; - } - cacheFile = arguments.at(i); - } else if (arguments.at(i).toLower() == QLatin1String("-d")) { - Option::debug_level++; - } else if (arguments.at(i).toLower() == QLatin1String("-timeout")) { - if (++i == arguments.size()) { - cout << "Error: No timeout value specified!" << endl; - return -1; - } - timeout = QString(arguments.at(i)).toInt(); - } else { - launchArguments.append(arguments.at(i)); - } - } - - // check for .pro file - if (proFile.isEmpty()) { - proFile = QDir::current().dirName() + QLatin1String(".pro"); - if (!QFileInfo(proFile).exists()) { - cout << "Error: Could not find project file in current directory." << endl; - return -1; - } - debugOutput(QString::fromLatin1("Using Project File:").append(proFile),1); - }else { - if (!QFileInfo(proFile).exists()) { - cout << "Error: Project file does not exist " << qPrintable(proFile) << endl; - return -1; - } - } - - Option::before_user_vars.append("CONFIG+=build_pass"); - - // read target and deployment rules passing the .pro to use instead of - // relying on qmake guessing the .pro to use - int qmakeArgc = 2; - QByteArray ba(QFile::encodeName(proFile)); - char* proFileEncodedName = ba.data(); - char* qmakeArgv[2] = { "qmake.exe", proFileEncodedName }; - - Option::qmake_mode = Option::QMAKE_GENERATE_NOTHING; - Option::output_dir = qmake_getpwd(); - if (!cacheFile.isEmpty()) - Option::mkfile::cachefile = cacheFile; - int ret = Option::init(qmakeArgc, qmakeArgv); - if(ret != Option::QMAKE_CMDLINE_SUCCESS) { - cout << "Error: could not parse " << qPrintable(proFile) << endl; - return -1; - } - - QMakeProperty prop; - QMakeProject project(&prop); - - project.read(proFile); - if (project.values("TEMPLATE").join(" ").toLower() != QString("app")) { - cout << "Error: Can only test executables!" << endl; - return -1; - } - // Check whether the project is still in debug/release mode after reading - // If .pro specifies to be one mode only, we need to accept this - if (project.isActiveConfig("debug") && !project.isActiveConfig("release")) { - TestConfiguration::testDebug = true; - debugOutput("ActiveConfig: debug only in .pro.", 1); - } - if (!project.isActiveConfig("debug") && project.isActiveConfig("release")) { - TestConfiguration::testDebug = false; - debugOutput("ActiveConfig: release only in .pro.", 1); - } - - // determine what is the real mkspec to use if the default mkspec is being used - if (Option::mkfile::qmakespec.endsWith("/default")) - project.values("QMAKESPEC") = project.values("QMAKESPEC_ORIGINAL"); - else - project.values("QMAKESPEC") = QStringList() << Option::mkfile::qmakespec; - - // ensure that QMAKESPEC is non-empty .. to meet requirements of QList::at() - if (project.values("QMAKESPEC").isEmpty()){ - cout << "Error: QMAKESPEC not set after parsing " << qPrintable(proFile) << endl; - return -1; - } - - // ensure that QT_CE_C_RUNTIME is non-empty .. to meet requirements of QList::at() - if (project.values("QT_CE_C_RUNTIME").isEmpty()){ - cout << "Error: QT_CE_C_RUNTIME not defined in mkspec/qconfig.pri " << qPrintable(project.values("QMAKESPEC").join(" ")); - return -1; - } - - QString destDir = project.values("DESTDIR").join(" "); - if (!destDir.isEmpty()) { - if (QDir::isRelativePath(destDir)) { - QFileInfo fi(proFile); - if (destDir == QLatin1String(".")) - destDir = fi.absolutePath() + "/" + destDir + "/" + (TestConfiguration::testDebug ? "debug" : "release"); - else - destDir = fi.absolutePath() + QDir::separator() + destDir; - } - } else { - QFileInfo fi(proFile); - destDir = fi.absolutePath(); - destDir += QDir::separator() + QLatin1String(TestConfiguration::testDebug ? "debug" : "release"); - } - - DeploymentList qtDeploymentList; - DeploymentList projectDeploymentList; - - TestConfiguration::localExecutable = Option::fixPathToLocalOS(destDir + QDir::separator() + project.values("TARGET").join(" ") + QLatin1String(".exe")); - TestConfiguration::remoteTestPath = QLatin1String("\\Program Files\\") + Option::fixPathToLocalOS(project.values("TARGET").join(QLatin1String(" "))); - if (!arguments.contains(QLatin1String("-libpath"), Qt::CaseInsensitive)) - TestConfiguration::remoteLibraryPath = TestConfiguration::remoteTestPath; - - QString targetExecutable = Option::fixPathToLocalOS(project.values("TARGET").join(QLatin1String(" "))); - int last = targetExecutable.lastIndexOf(QLatin1Char('\\')); - targetExecutable = targetExecutable.mid( last == -1 ? 0 : last+1 ); - TestConfiguration::remoteExecutable = TestConfiguration::remoteTestPath + QDir::separator() + targetExecutable + QLatin1String(".exe"); - projectDeploymentList.append(CopyItem(TestConfiguration::localExecutable , TestConfiguration::remoteExecutable)); - - // deploy -#ifdef QT_CETEST_NO_ACTIVESYNC - CeTcpSyncConnection connection; -#else - ActiveSyncConnection connection; -#endif - if (!connection.connect()) { - cout << "Error: Could not connect to device!" << endl; - return -1; - } - DeploymentHandler deployment; - deployment.setConnection(&connection); - - deployment.initQtDeploy(&project, qtDeploymentList, TestConfiguration::remoteLibraryPath); - deployment.initProjectDeploy(&project , projectDeploymentList, TestConfiguration::remoteTestPath); - - // add qt.conf - if (TestConfiguration::localQtConf != QLatin1String("no")) { - QString qtConfOrigin = QFileInfo(TestConfiguration::localQtConf).absoluteFilePath(); - QString qtConfTarget = Option::fixPathToLocalOS(TestConfiguration::remoteTestPath + QDir::separator() + QLatin1String("qt.conf")); - projectDeploymentList.append(CopyItem(qtConfOrigin, qtConfTarget)); - } - - if (!deployment.deviceDeploy(qtDeploymentList) || !deployment.deviceDeploy(projectDeploymentList)) { - cout << "Error: Could not copy file(s) to device" << endl; - return -1; - } - // device power mode - if (keepAwake) - { - int retVal = 0; - if (!connection.setDeviceAwake(true, &retVal)) { - cout << "Error: Could not set unattended mode on device" << endl; - return -1; - } - } - - // reset device - if (deviceReset) - { - if (!connection.resetDevice()) { - //if (!connection.toggleDevicePower( &retVal)) { - cout << "Error: Could not reset the device" << endl; - return -1; - } - cout << " Entering sleep after reset for " << SLEEP_AFTER_RESET / 1000 << " seconds ... " << endl; - Sleep(SLEEP_AFTER_RESET); - cout << " ... woke up. " << endl; - connection.disconnect(); - // reconnect after reset - int retryCount = 21; - while (--retryCount) - { - if (!connection.connect()) - Sleep(SLEEP_RECONNECT); - else - break; - } - if (!connection.isConnected()) - { - cout << "Error: Could not connect to device!" << endl; - return -1; - } - } - - // launch - launchArguments.append("-o"); - launchArguments.append(TestConfiguration::remoteResultFile); - - cout << endl << "Remote Launch:" << qPrintable(TestConfiguration::remoteExecutable) << " " << qPrintable(launchArguments.join(" ")) << endl; - if (!connection.execute(TestConfiguration::remoteExecutable, launchArguments.join(" "), timeout)) { - cout << "Error: Could not execute target file" << endl; - return -1; - } - - - // copy result file - // show results - if (resultFile.isEmpty()) { - QString tempResultFile = Option::fixPathToLocalOS(QDir::tempPath() + "/qt_ce_temp_result_file.txt"); - if (connection.copyFileFromDevice(TestConfiguration::remoteResultFile, tempResultFile)) { - QFile file(tempResultFile); - QByteArray arr; - if (file.open(QIODevice::ReadOnly)) { - arr = file.readAll(); - cout << arr.constData() << endl; - } - file.close(); - file.remove(); - } - } else { - connection.copyFileFromDevice(TestConfiguration::remoteResultFile, resultFile); - } - - // delete - connection.deleteFile(TestConfiguration::remoteResultFile); - if (cleanupQt) - deployment.cleanup(qtDeploymentList); - if (cleanupProject) - deployment.cleanup(projectDeploymentList); - return 0; -} diff --git a/src/qtestlib/wince/cetest/qmake_include.pri b/src/qtestlib/wince/cetest/qmake_include.pri deleted file mode 100644 index bc2dd44e2..000000000 --- a/src/qtestlib/wince/cetest/qmake_include.pri +++ /dev/null @@ -1,11 +0,0 @@ -#qmake source files needed for cetest -HEADERS += \ - $$QT.core.sources/../../qmake/option.h -SOURCES += \ - $$QT.core.sources/../../qmake/option.cpp \ - $$QT.core.sources/../../qmake/project.cpp \ - $$QT.core.sources/../../qmake/property.cpp \ - $$QT.core.sources/../../qmake/generators/metamakefile.cpp \ - $$QT.core.sources/../../tools/shared/windows/registry.cpp - -DEFINES += QT_QMAKE_PARSER_ONLY diff --git a/src/qtestlib/wince/cetest/remoteconnection.cpp b/src/qtestlib/wince/cetest/remoteconnection.cpp deleted file mode 100644 index 31118d423..000000000 --- a/src/qtestlib/wince/cetest/remoteconnection.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ - -#include "remoteconnection.h" - -QByteArray strwinerror(DWORD errorcode) -{ - QByteArray out(512, 0); - - DWORD ok = FormatMessageA( - FORMAT_MESSAGE_FROM_SYSTEM, - 0, - errorcode, - 0, - out.data(), - out.size(), - 0 - ); - - if (!ok) { - qsnprintf(out.data(), out.size(), - "(error %d; additionally, error %d while looking up error string)", - (int)errorcode, (int)GetLastError()); - } - else { - out.resize(qstrlen(out.constData())); - if (out.endsWith("\r\n")) - out.chop(2); - - /* Append error number to error message for good measure */ - out.append(" (0x"); - out.append(QByteArray::number(uint(errorcode), 16).rightJustified(8, '0')); - out.append(")"); - } - return out; -} - -AbstractRemoteConnection::AbstractRemoteConnection() -{ -} - -AbstractRemoteConnection::~AbstractRemoteConnection() -{ -} - - -// Slow but should be ok... -bool AbstractRemoteConnection::moveFile(const QString &src, const QString &dest, bool FailIfExists) -{ - bool result = copyFile(src, dest, FailIfExists); - deleteFile(src); - return result; -} - -// Slow but should be ok... -bool AbstractRemoteConnection::moveDirectory(const QString &src, const QString &dest, bool recursive) -{ - bool result = copyDirectory(src, dest, true); - deleteDirectory(src, recursive); - return result; -} - diff --git a/src/qtestlib/wince/cetest/remoteconnection.h b/src/qtestlib/wince/cetest/remoteconnection.h deleted file mode 100644 index 1b93a06cd..000000000 --- a/src/qtestlib/wince/cetest/remoteconnection.h +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ - -#ifndef REMOTECONNECTION_H -#define REMOTECONNECTION_H - -#include <QtCore/QString> -#include <QtCore/QVariant> -#include <windows.h> -class AbstractRemoteConnection -{ -public: - AbstractRemoteConnection(); - virtual ~AbstractRemoteConnection(); - - virtual bool connect(QVariantList&) = 0; - virtual void disconnect() = 0; - virtual bool isConnected() const = 0; - - // These functions are designed for transfer between desktop and device - // Caution: deviceDest path has to be device specific (eg. no drive letters for CE) - virtual bool copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists = false) = 0; - virtual bool copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive = true) = 0; - virtual bool copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists = false) = 0; - virtual bool copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive = true) = 0; - - // For "intelligent deployment" we need to investigate on filetimes on the device - virtual bool timeStampForLocalFileTime(FILETIME*) const = 0; - virtual bool fileCreationTime(const QString &fileName, FILETIME*) const = 0; - - // These functions only work on files existing on the device - virtual bool copyFile(const QString&, const QString&, bool failIfExists = false) = 0; - virtual bool copyDirectory(const QString&, const QString&, bool recursive = true) = 0; - virtual bool deleteFile(const QString&) = 0; - virtual bool deleteDirectory(const QString&, bool recursive = true, bool failIfContentExists = false) = 0; - bool moveFile(const QString&, const QString&, bool FailIfExists = false); - bool moveDirectory(const QString&, const QString&, bool recursive = true); - - virtual bool createDirectory(const QString&, bool deleteBefore=false) = 0; - - virtual bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL) = 0; -}; - -QByteArray strwinerror(DWORD); - -#endif diff --git a/src/qtestlib/wince/remotelib/commands.cpp b/src/qtestlib/wince/remotelib/commands.cpp deleted file mode 100644 index e496f9a8e..000000000 --- a/src/qtestlib/wince/remotelib/commands.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ -#include "commands.h" -#include <Pm.h> -#include <Pmpolicy.h> - - -#define CLEAN_FAIL(a) {delete appName; \ - delete arguments; \ - return (a); } - -int qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream) -{ - if (!stream) - return -1; - - DWORD bytesRead; - int appLength; - wchar_t* appName = 0; - int argumentsLength; - wchar_t* arguments = 0; - int timeout = -1; - int returnValue = -2; - DWORD error = 0; - - if (S_OK != stream->Read(&appLength, sizeof(appLength), &bytesRead)) - CLEAN_FAIL(-2); - appName = (wchar_t*) malloc(sizeof(wchar_t)*(appLength + 1)); - if (S_OK != stream->Read(appName, sizeof(wchar_t)*appLength, &bytesRead)) - CLEAN_FAIL(-2); - appName[appLength] = '\0'; - - if (S_OK != stream->Read(&argumentsLength, sizeof(argumentsLength), &bytesRead)) - CLEAN_FAIL(-2); - arguments = (wchar_t*) malloc(sizeof(wchar_t)*(argumentsLength + 1)); - if (S_OK != stream->Read(arguments, sizeof(wchar_t)*argumentsLength, &bytesRead)) - CLEAN_FAIL(-2); - arguments[argumentsLength] = '\0'; - - if (S_OK != stream->Read(&timeout, sizeof(timeout), &bytesRead)) - CLEAN_FAIL(-2); - - bool result = qRemoteExecute(appName, arguments, &returnValue, &error, timeout); - - if (timeout != 0) { - if (S_OK != stream->Write(&returnValue, sizeof(returnValue), &bytesRead)) - CLEAN_FAIL(-4); - if (S_OK != stream->Write(&error, sizeof(error), &bytesRead)) - CLEAN_FAIL(-5); - } - delete appName; - delete arguments; - // We need to fail here for the execute, otherwise the calling application will wait - // forever for the returnValue. - if (!result) - return -3; - return S_OK; -} - - -bool qRemoteExecute(const wchar_t* program, const wchar_t* arguments, int *returnValue, DWORD* error, int timeout) -{ - *error = 0; - - if (!program) - return false; - - PROCESS_INFORMATION pid; - if (!CreateProcess(program, arguments, NULL, NULL, false, 0, NULL, NULL, NULL, &pid)) { - *error = GetLastError(); - wprintf(L"Could not launch: %s\n", program); - return false; - } - - // Timeout is in seconds - DWORD waitingTime = (timeout == -1) ? INFINITE : timeout * 1000; - - if (waitingTime != 0) { - DWORD waitStatus = WaitForSingleObject(pid.hProcess, waitingTime); - if (waitStatus == WAIT_TIMEOUT) { - TerminateProcess(pid.hProcess, 2); - return false; - } else if (waitStatus == WAIT_OBJECT_0 && returnValue) { - *returnValue = 0; - DWORD exitCode; - if (GetExitCodeProcess(pid.hProcess, &exitCode)) - *returnValue = exitCode; - } - } - return true; -} -/** -\brief Reset the device. -*/ -int qRemoteSoftReset(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream) -{ - //POWER_STATE_ON On state - //POWER_STATE_OFF Off state - //POWER_STATE_CRITICAL Critical state - //POWER_STATE_BOOT Boot state - //POWER_STATE_IDLE Idle state - //POWER_STATE_SUSPEND Suspend state - //POWER_STATE_RESET Reset state - - DWORD returnValue = SetSystemPowerState(0, POWER_STATE_RESET, POWER_FORCE); - return returnValue; -} - -/** -\brief Toggle the unattended powermode of the device -*/ -int qRemoteToggleUnattendedPowerMode(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream) -{ - if (!stream) - return -1; - - DWORD bytesRead; - int toggleVal = 0; - int returnValue = S_OK; - - if (S_OK != stream->Read(&toggleVal, sizeof(toggleVal), &bytesRead)) - return -2; - - //PPN_REEVALUATESTATE 0x0001 Reserved. Set dwData to zero (0). - //PPN_POWERCHANGE 0x0002 Reserved. Set dwData to zero (0). - //PPN_UNATTENDEDMODE 0x0003 Set dwData to TRUE or FALSE. - //PPN_SUSPENDKEYPRESSED or - //PPN_POWERBUTTONPRESSED 0x0004 Reserved. Set dwData to zero (0). - //PPN_SUSPENDKEYRELEASED 0x0005 Reserved. Set dwData to zero (0). - //PPN_APPBUTTONPRESSED 0x0006 Reserved. Set dwData to zero (0). - //PPN_OEMBASE Greater than or equal to 0x10000 - //You can define higher values, such as 0x10001, 0x10002, and so on. - // Reserved. Set dwData to zero (0). - returnValue = PowerPolicyNotify(PPN_UNATTENDEDMODE, toggleVal); - - if (S_OK != stream->Write(&returnValue, sizeof(returnValue), &bytesRead)) - return -3; - else - return S_OK; -} - -/** -\brief Virtually press the power button of the device -*/ -int qRemotePowerButton(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream) -{ - if (!stream) - return -1; - - DWORD bytesRead; - int toggleVal = 0; - int returnValue = S_OK; - - if (S_OK != stream->Read(&toggleVal, sizeof(toggleVal), &bytesRead)) - return -2; - - //PPN_REEVALUATESTATE 0x0001 Reserved. Set dwData to zero (0). - //PPN_POWERCHANGE 0x0002 Reserved. Set dwData to zero (0). - //PPN_UNATTENDEDMODE 0x0003 Set dwData to TRUE or FALSE. - //PPN_SUSPENDKEYPRESSED or - //PPN_POWERBUTTONPRESSED 0x0004 Reserved. Set dwData to zero (0). - //PPN_SUSPENDKEYRELEASED 0x0005 Reserved. Set dwData to zero (0). - //PPN_APPBUTTONPRESSED 0x0006 Reserved. Set dwData to zero (0). - //PPN_OEMBASE Greater than or equal to 0x10000 - //You can define higher values, such as 0x10001, 0x10002, and so on. - // Reserved. Set dwData to zero (0). - returnValue = PowerPolicyNotify(PPN_SUSPENDKEYPRESSED, 0); - - if (S_OK != stream->Write(&returnValue, sizeof(returnValue), &bytesRead)) - return -3; - else - return S_OK; -} - diff --git a/src/qtestlib/wince/remotelib/commands.h b/src/qtestlib/wince/remotelib/commands.h deleted file mode 100644 index fc21d03ef..000000000 --- a/src/qtestlib/wince/remotelib/commands.h +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ -#ifndef QREMOTECOMMANDS_H -#define QREMOTECOMMANDS_H -#include <winbase.h> -#include <rapi.h> - -extern "C" { - int __declspec(dllexport) qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream*); - int __declspec(dllexport) qRemoteSoftReset(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream); - int __declspec(dllexport) qRemoteToggleUnattendedPowerMode(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream); - int __declspec(dllexport) qRemotePowerButton(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream); - bool __declspec(dllexport) qRemoteExecute(const wchar_t* program, const wchar_t* arguments = NULL, int *returnValue = NULL , DWORD* error = NULL, int timeout = -1); -} - -#endif diff --git a/src/qtestlib/wince/remotelib/remotelib.pro b/src/qtestlib/wince/remotelib/remotelib.pro deleted file mode 100644 index c2438b350..000000000 --- a/src/qtestlib/wince/remotelib/remotelib.pro +++ /dev/null @@ -1,12 +0,0 @@ -TEMPLATE = lib -CONFIG += dll -CONFIG -= staticlib -TARGET = QtRemote -DESTDIR = ../../../../lib -QT = - -HEADERS += commands.h -SOURCES += commands.cpp - -INCLUDEPATH += $$QT_CE_RAPI_INC -LIBS += -L$$QT_CE_RAPI_LIB diff --git a/src/qtestlib/wince/wince.pro b/src/qtestlib/wince/wince.pro deleted file mode 100644 index 7c88d6572..000000000 --- a/src/qtestlib/wince/wince.pro +++ /dev/null @@ -1,2 +0,0 @@ -TEMPLATE = subdirs -wince*:SUBDIRS = remotelib
\ No newline at end of file diff --git a/src/shared/deviceskin/deviceskin.cpp b/src/shared/deviceskin/deviceskin.cpp index 5ac2eed7a..02deecb01 100644 --- a/src/shared/deviceskin/deviceskin.cpp +++ b/src/shared/deviceskin/deviceskin.cpp @@ -78,12 +78,6 @@ static QString msgImageNotLoaded(const QString &f) { } // ------------ DeviceSkinButtonArea -DeviceSkinButtonArea::DeviceSkinButtonArea() : - keyCode(0), - activeWhenClosed(0) -{ -} - QDebug &operator<<(QDebug &str, const DeviceSkinButtonArea &a) { diff --git a/src/shared/deviceskin/deviceskin.h b/src/shared/deviceskin/deviceskin.h index bf0bb77ee..52c4848c2 100644 --- a/src/shared/deviceskin/deviceskin.h +++ b/src/shared/deviceskin/deviceskin.h @@ -56,14 +56,13 @@ class QTextStream; // ------- Button Area struct DeviceSkinButtonArea { - DeviceSkinButtonArea(); QString name; - int keyCode; + int keyCode{0}; QPolygon area; QString text; - bool activeWhenClosed; - bool toggleArea; - bool toggleActiveArea; + bool activeWhenClosed{false}; + bool toggleArea{false}; + bool toggleActiveArea{false}; }; // -------- Parameters diff --git a/src/shared/qtpropertybrowser/qtbuttonpropertybrowser.cpp b/src/shared/qtpropertybrowser/qtbuttonpropertybrowser.cpp index e2c18d9a9..cf0fc1a19 100644 --- a/src/shared/qtpropertybrowser/qtbuttonpropertybrowser.cpp +++ b/src/shared/qtpropertybrowser/qtbuttonpropertybrowser.cpp @@ -68,17 +68,15 @@ public: struct WidgetItem { - WidgetItem() : widget(0), label(0), widgetLabel(0), - button(0), container(0), layout(0), /*line(0), */parent(0), expanded(false) { } - QWidget *widget; // can be null - QLabel *label; // main label with property name - QLabel *widgetLabel; // label substitute showing the current value if there is no widget - QToolButton *button; // expandable button for items with children - QWidget *container; // container which is expanded when the button is clicked - QGridLayout *layout; // layout in container - WidgetItem *parent; + QWidget *widget{nullptr}; // can be null + QLabel *label{nullptr}; // main label with property name + QLabel *widgetLabel{nullptr}; // label substitute showing the current value if there is no widget + QToolButton *button{nullptr}; // expandable button for items with children + QWidget *container{nullptr}; // container which is expanded when the button is clicked + QGridLayout *layout{nullptr}; // layout in container + WidgetItem *parent{nullptr}; QList<WidgetItem *> children; - bool expanded; + bool expanded{false}; }; private: void updateLater(); diff --git a/src/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp b/src/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp index fc9694c93..015a36baf 100644 --- a/src/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp +++ b/src/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp @@ -66,15 +66,13 @@ public: struct WidgetItem { - WidgetItem() : widget(0), label(0), widgetLabel(0), - groupBox(0), layout(0), line(0), parent(0) { } - QWidget *widget; // can be null - QLabel *label; - QLabel *widgetLabel; - QGroupBox *groupBox; - QGridLayout *layout; - QFrame *line; - WidgetItem *parent; + QWidget *widget{nullptr}; // can be null + QLabel *label{nullptr}; + QLabel *widgetLabel{nullptr}; + QGroupBox *groupBox{nullptr}; + QGridLayout *layout{nullptr}; + QFrame *line{nullptr}; + WidgetItem *parent{nullptr}; QList<WidgetItem *> children; }; private: diff --git a/src/shared/qtpropertybrowser/qtpropertymanager.cpp b/src/shared/qtpropertybrowser/qtpropertymanager.cpp index 3fa6fc546..14b6125fd 100644 --- a/src/shared/qtpropertybrowser/qtpropertymanager.cpp +++ b/src/shared/qtpropertybrowser/qtpropertymanager.cpp @@ -589,11 +589,10 @@ public: struct Data { - Data() : val(0), minVal(-INT_MAX), maxVal(INT_MAX), singleStep(1) {} - int val; - int minVal; - int maxVal; - int singleStep; + int val{0}; + int minVal{-INT_MAX}; + int maxVal{INT_MAX}; + int singleStep{1}; int minimumValue() const { return minVal; } int maximumValue() const { return maxVal; } void setMinimumValue(int newMinVal) { setSimpleMinimumData(this, newMinVal); } @@ -866,12 +865,11 @@ public: struct Data { - Data() : val(0), minVal(-DBL_MAX), maxVal(DBL_MAX), singleStep(1), decimals(2) {} - double val; - double minVal; - double maxVal; - double singleStep; - int decimals; + double val{0}; + double minVal{-DBL_MAX}; + double maxVal{DBL_MAX}; + double singleStep{1}; + int decimals{2}; double minimumValue() const { return minVal; } double maximumValue() const { return maxVal; } void setMinimumValue(double newMinVal) { setSimpleMinimumData(this, newMinVal); } @@ -1549,11 +1547,9 @@ public: struct Data { - Data() : val(QDate::currentDate()), minVal(QDate(1752, 9, 14)), - maxVal(QDate(7999, 12, 31)) {} - QDate val; - QDate minVal; - QDate maxVal; + QDate val{QDate::currentDate()}; + QDate minVal{QDate(1752, 9, 14)}; + QDate maxVal{QDate(7999, 12, 31)}; QDate minimumValue() const { return minVal; } QDate maximumValue() const { return maxVal; } void setMinimumValue(const QDate &newMinVal) { setSimpleMinimumData(this, newMinVal); } @@ -2712,9 +2708,8 @@ public: struct Data { - Data() : decimals(2) {} QPointF val; - int decimals; + int decimals{2}; }; void slotDoubleChanged(QtProperty *property, double value); @@ -2995,10 +2990,9 @@ public: struct Data { - Data() : val(QSize(0, 0)), minVal(QSize(0, 0)), maxVal(QSize(INT_MAX, INT_MAX)) {} - QSize val; - QSize minVal; - QSize maxVal; + QSize val{0, 0}; + QSize minVal{0, 0}; + QSize maxVal{INT_MAX, INT_MAX}; QSize minimumValue() const { return minVal; } QSize maximumValue() const { return maxVal; } void setMinimumValue(const QSize &newMinVal) { setSizeMinimumData(this, newMinVal); } @@ -3340,11 +3334,10 @@ public: struct Data { - Data() : val(QSizeF(0, 0)), minVal(QSizeF(0, 0)), maxVal(QSizeF(INT_MAX, INT_MAX)), decimals(2) {} - QSizeF val; - QSizeF minVal; - QSizeF maxVal; - int decimals; + QSizeF val{0, 0}; + QSizeF minVal{0, 0}; + QSizeF maxVal{INT_MAX, INT_MAX}; + int decimals{2}; QSizeF minimumValue() const { return minVal; } QSizeF maximumValue() const { return maxVal; } void setMinimumValue(const QSizeF &newMinVal) { setSizeMinimumData(this, newMinVal); } @@ -3739,8 +3732,7 @@ public: struct Data { - Data() : val(0, 0, 0, 0) {} - QRect val; + QRect val{0, 0, 0, 0}; QRect constraint; }; @@ -4148,10 +4140,9 @@ public: struct Data { - Data() : val(0, 0, 0, 0), decimals(2) {} - QRectF val; + QRectF val{0, 0, 0, 0}; QRectF constraint; - int decimals; + int decimals{2}; }; typedef QMap<const QtProperty *, Data> PropertyValueMap; @@ -4615,8 +4606,7 @@ public: struct Data { - Data() : val(-1) {} - int val; + int val{-1}; QStringList enumNames; QMap<int, QIcon> enumIcons; }; @@ -4888,8 +4878,7 @@ public: struct Data { - Data() : val(-1) {} - int val; + int val{-1}; QStringList flagNames; }; diff --git a/src/shared/qttoolbardialog/qttoolbardialog.cpp b/src/shared/qttoolbardialog/qttoolbardialog.cpp index 7b1083bcb..d13f57265 100644 --- a/src/shared/qttoolbardialog/qttoolbardialog.cpp +++ b/src/shared/qttoolbardialog/qttoolbardialog.cpp @@ -145,8 +145,6 @@ public: QToolBar *toolBarByName(const QString &toolBarName) const; - QtFullToolBarManagerPrivate(); - QMap<QString, QList<QAction *> > categoryToActions; QMap<QAction *, QString> actionToCategory; @@ -160,17 +158,9 @@ public: QMap<QToolBar *, QList<QAction *> > defaultToolBars; QList<QToolBar *> customToolBars; - QMainWindow *theMainWindow; + QMainWindow *theMainWindow{nullptr}; }; - - - -QtFullToolBarManagerPrivate::QtFullToolBarManagerPrivate() - : theMainWindow(0) -{ -} - QToolBar *QtFullToolBarManagerPrivate::toolBarWidgetAction(QAction *action) const { if (widgetActions.contains(action)) @@ -761,7 +751,7 @@ QByteArray QtFullToolBarManager::saveState(int version) const { QByteArray data; QDataStream stream(&data, QIODevice::WriteOnly); - stream << QtFullToolBarManagerPrivate::VersionMarker; + stream << int(QtFullToolBarManagerPrivate::VersionMarker); stream << version; d_ptr->saveState(stream); return data; diff --git a/src/src.pro b/src/src.pro index 387d54f70..db6fe0c3b 100644 --- a/src/src.pro +++ b/src/src.pro @@ -6,7 +6,6 @@ qtHaveModule(widgets) { } else { SUBDIRS = assistant \ pixeltool \ - qtestlib \ designer linguist.depends = designer @@ -15,8 +14,11 @@ qtHaveModule(widgets) { SUBDIRS += linguist \ qdoc \ - qtplugininfo -if(!android|android_app):!ios: SUBDIRS += qtpaths + qtattributionsscanner + +!android|android_app: SUBDIRS += qtplugininfo + +if(!android|android_app):!uikit: SUBDIRS += qtpaths mac { SUBDIRS += macdeployqt @@ -30,7 +32,7 @@ qtHaveModule(dbus): SUBDIRS += qdbus win32|winrt:SUBDIRS += windeployqt winrt:SUBDIRS += winrtrunner -qtHaveModule(gui):!android:!ios:!qnx:!wince*:!winrt*:SUBDIRS += qtdiag +qtHaveModule(gui):!android:!uikit:!qnx:!winrt: SUBDIRS += qtdiag qtNomakeTools( \ pixeltool \ diff --git a/src/windeployqt/main.cpp b/src/windeployqt/main.cpp index 4f9603e69..2b2425982 100644 --- a/src/windeployqt/main.cpp +++ b/src/windeployqt/main.cpp @@ -349,7 +349,7 @@ static inline int parseArguments(const QStringList &arguments, QCommandLineParse parser->addOption(releaseOption); QCommandLineOption releaseWithDebugInfoOption(QStringLiteral("release-with-debug-info"), QStringLiteral("Assume release binaries with debug information.")); - releaseWithDebugInfoOption.setHidden(true); // Deprecated by improved debug detection. + releaseWithDebugInfoOption.setFlags(QCommandLineOption::HiddenFromHelp); // Deprecated by improved debug detection. parser->addOption(releaseWithDebugInfoOption); QCommandLineOption deployPdbOption(QStringLiteral("pdb"), diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 20b5fec90..53466702f 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -1,6 +1,7 @@ TEMPLATE=subdirs SUBDIRS=\ linguist \ + qtattributionsscanner \ qhelpcontentmodel \ qhelpenginecore \ qhelpgenerator \ @@ -24,5 +25,5 @@ cross_compile:SUBDIRS -= linguist qhelpindexmodel \ qhelpprojectdata \ -android|ios|qnx|wince*|winrt*:SUBDIRS -= qtdiag -!win32|wince*|winrt*:SUBDIRS -= windeployqt +android|ios|qnx|winrt: SUBDIRS -= qtdiag +!win32|winrt: SUBDIRS -= windeployqt diff --git a/tests/auto/qhelpcontentmodel/qhelpcontentmodel.pro b/tests/auto/qhelpcontentmodel/qhelpcontentmodel.pro index 13a7d47bb..7fb9f6585 100644 --- a/tests/auto/qhelpcontentmodel/qhelpcontentmodel.pro +++ b/tests/auto/qhelpcontentmodel/qhelpcontentmodel.pro @@ -3,19 +3,4 @@ CONFIG += testcase QT += help testlib SOURCES += tst_qhelpcontentmodel.cpp -DEFINES += QT_USE_USING_NAMESPACE - -wince*: { - DEFINES += SRCDIR=\\\"./\\\" - QT += network - addFiles.files = $$PWD/data/*.* - addFiles.path = data - clucene.files = $$QT.clucene.libs/QtCLucene*.dll - - DEPLOYMENT += addFiles - DEPLOYMENT += clucene - - DEPLOYMENT_PLUGIN += qsqlite -} else { - DEFINES += SRCDIR=\\\"$$PWD\\\" -} +DEFINES += QT_USE_USING_NAMESPACE SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/qhelpenginecore/qhelpenginecore.pro b/tests/auto/qhelpenginecore/qhelpenginecore.pro index 4fa425838..e6fc35074 100644 --- a/tests/auto/qhelpenginecore/qhelpenginecore.pro +++ b/tests/auto/qhelpenginecore/qhelpenginecore.pro @@ -4,19 +4,4 @@ SOURCES += tst_qhelpenginecore.cpp QT += help sql testlib help -DEFINES += QT_USE_USING_NAMESPACE - -wince*: { - DEFINES += SRCDIR=\\\"./\\\" - QT += network - addFiles.files = $$PWD/data/*.* - addFiles.path = data - clucene.files = $$QT.clucene.libs/QtCLucene*.dll - - DEPLOYMENT += addFiles - DEPLOYMENT += clucene - - DEPLOYMENT_PLUGIN += qsqlite -} else { - DEFINES += SRCDIR=\\\"$$PWD\\\" -} +DEFINES += QT_USE_USING_NAMESPACE SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/qtattributionsscanner/qtattributionsscanner.pro b/tests/auto/qtattributionsscanner/qtattributionsscanner.pro new file mode 100644 index 000000000..aa8442a88 --- /dev/null +++ b/tests/auto/qtattributionsscanner/qtattributionsscanner.pro @@ -0,0 +1,18 @@ +CONFIG += testcase +QT = core testlib + +DISTFILES += \ + testdata/good/minimal/qt_attribution.json \ + testdata/good/complete/qt_attribution.json \ + testdata/good/expected.json \ + testdata/good/expected.error \ + testdata/warnings/incomplete/qt_attribution.json \ + testdata/warnings/incomplete/expected.json \ + testdata/warnings/incomplete/expected.error \ + testdata/warnings/unknown/qt_attribution.json \ + testdata/warnings/unknown/expected.json \ + testdata/warnings/unknown/expected.error + +TARGET = tst_qtattributionsscanner + +SOURCES += tst_qtattributionsscanner.cpp diff --git a/tests/auto/qtattributionsscanner/testdata/good/complete/qt_attribution.json b/tests/auto/qtattributionsscanner/testdata/good/complete/qt_attribution.json new file mode 100644 index 000000000..eaebdb9ef --- /dev/null +++ b/tests/auto/qtattributionsscanner/testdata/good/complete/qt_attribution.json @@ -0,0 +1,20 @@ +{ + "Id": "complete", + "Name": "Complete", + "QDocModule": "qtest", + + "License": "License", + "Copyright": "Copyright", + + "Description": "Multi +Line +Description", + "QtUsage": "Multi +Line +Usage", + "Homepage": "www.qt.io", + "Version": "1.0", + "DownloadLocation": "www.qt.io/1.0", + "LicenseId": "xxx", + "LicenseFile": "LICENSE" +} diff --git a/tests/auto/qtattributionsscanner/testdata/good/expected.error b/tests/auto/qtattributionsscanner/testdata/good/expected.error new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/auto/qtattributionsscanner/testdata/good/expected.error diff --git a/tests/auto/qtattributionsscanner/testdata/good/expected.json b/tests/auto/qtattributionsscanner/testdata/good/expected.json new file mode 100644 index 000000000..2a076d650 --- /dev/null +++ b/tests/auto/qtattributionsscanner/testdata/good/expected.json @@ -0,0 +1,34 @@ +[ + { + "Copyright": "Copyright", + "Description": "Multi\nLine\nDescription", + "Homepage": "www.qt.io", + "Id": "complete", + "License": "License", + "LicenseFile": "%{PWD}/complete/LICENSE", + "LicenseId": "xxx", + "Name": "Complete", + "Path": "%{PWD}/complete", + "Files": "", + "QDocModule": "qtest", + "QtUsage": "Multi\nLine\nUsage", + "Version": "1.0", + "DownloadLocation": "www.qt.io/1.0" + }, + { + "Copyright": "Copyright", + "Description": "", + "Homepage": "", + "Id": "minimal", + "License": "License", + "LicenseFile": "", + "LicenseId": "", + "Name": "Minimal", + "Path": "%{PWD}/minimal", + "Files": "", + "QDocModule": "qtest", + "QtUsage": "Usage", + "Version": "", + "DownloadLocation": "" + } +] diff --git a/tests/auto/qtattributionsscanner/testdata/good/minimal/qt_attribution.json b/tests/auto/qtattributionsscanner/testdata/good/minimal/qt_attribution.json new file mode 100644 index 000000000..2dc53f852 --- /dev/null +++ b/tests/auto/qtattributionsscanner/testdata/good/minimal/qt_attribution.json @@ -0,0 +1,9 @@ +{ + "Id": "minimal", + "Name": "Minimal", + + "QDocModule": "qtest", + "QtUsage": "Usage", + "License": "License", + "Copyright": "Copyright" +} diff --git a/tests/auto/qtattributionsscanner/testdata/warnings/incomplete/expected.error b/tests/auto/qtattributionsscanner/testdata/warnings/incomplete/expected.error new file mode 100644 index 000000000..e18d2976b --- /dev/null +++ b/tests/auto/qtattributionsscanner/testdata/warnings/incomplete/expected.error @@ -0,0 +1,6 @@ +File %{PWD}/qt_attribution.json: Missing mandatory property 'Name'. +File %{PWD}/qt_attribution.json: Missing mandatory property 'Id'. +File %{PWD}/qt_attribution.json: Missing mandatory property 'QDocModule'. +File %{PWD}/qt_attribution.json: Missing mandatory property 'QtUsage'. +File %{PWD}/qt_attribution.json: Missing mandatory property 'License'. +File %{PWD}/qt_attribution.json: Missing mandatory property 'Copyright'. diff --git a/tests/auto/qtattributionsscanner/testdata/warnings/incomplete/expected.json b/tests/auto/qtattributionsscanner/testdata/warnings/incomplete/expected.json new file mode 100644 index 000000000..5ddb2d32d --- /dev/null +++ b/tests/auto/qtattributionsscanner/testdata/warnings/incomplete/expected.json @@ -0,0 +1,18 @@ +[ + { + "Copyright": "", + "Description": "", + "Homepage": "", + "Id": "", + "License": "", + "LicenseFile": "", + "LicenseId": "", + "Name": "", + "Path": "%{PWD}", + "Files": "", + "QDocModule": "", + "QtUsage": "", + "Version": "", + "DownloadLocation": "" + } +] diff --git a/tests/auto/qtattributionsscanner/testdata/warnings/incomplete/qt_attribution.json b/tests/auto/qtattributionsscanner/testdata/warnings/incomplete/qt_attribution.json new file mode 100644 index 000000000..2c63c0851 --- /dev/null +++ b/tests/auto/qtattributionsscanner/testdata/warnings/incomplete/qt_attribution.json @@ -0,0 +1,2 @@ +{ +} diff --git a/tests/auto/qtattributionsscanner/testdata/warnings/unknown/expected.error b/tests/auto/qtattributionsscanner/testdata/warnings/unknown/expected.error new file mode 100644 index 000000000..89b48074b --- /dev/null +++ b/tests/auto/qtattributionsscanner/testdata/warnings/unknown/expected.error @@ -0,0 +1 @@ +File %{PWD}/qt_attribution.json: Unknown key Unknown. diff --git a/tests/auto/qtattributionsscanner/testdata/warnings/unknown/expected.json b/tests/auto/qtattributionsscanner/testdata/warnings/unknown/expected.json new file mode 100644 index 000000000..da2febe18 --- /dev/null +++ b/tests/auto/qtattributionsscanner/testdata/warnings/unknown/expected.json @@ -0,0 +1,18 @@ +[ + { + "Copyright": "Copyright", + "Description": "", + "Homepage": "", + "Id": "unknown", + "License": "License", + "LicenseFile": "", + "LicenseId": "", + "Name": "Unknown", + "Path": "%{PWD}", + "Files": "", + "QDocModule": "qtest", + "QtUsage": "Usage", + "Version": "", + "DownloadLocation": "" + } +] diff --git a/tests/auto/qtattributionsscanner/testdata/warnings/unknown/qt_attribution.json b/tests/auto/qtattributionsscanner/testdata/warnings/unknown/qt_attribution.json new file mode 100644 index 000000000..f1d55638c --- /dev/null +++ b/tests/auto/qtattributionsscanner/testdata/warnings/unknown/qt_attribution.json @@ -0,0 +1,10 @@ +{ + "Id": "unknown", + "Name": "Unknown", + "QDocModule": "qtest", + + "QtUsage": "Usage", + "License": "License", + "Copyright": "Copyright", + "Unknown": "Unknown" +} diff --git a/tests/auto/qtattributionsscanner/tst_qtattributionsscanner.cpp b/tests/auto/qtattributionsscanner/tst_qtattributionsscanner.cpp new file mode 100644 index 000000000..c3e8bb9b6 --- /dev/null +++ b/tests/auto/qtattributionsscanner/tst_qtattributionsscanner.cpp @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Linguist of the Qt Toolkit. +** +** $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$ +** +****************************************************************************/ + +#include <QtCore/qdir.h> +#include <QtCore/qdebug.h> +#include <QtCore/qfile.h> +#include <QtCore/qbytearray.h> +#include <QtCore/qjsondocument.h> +#include <QtCore/qlibraryinfo.h> +#include <QtCore/qprocess.h> + +#include <QtTest/qtest.h> + +class tst_qtattributionsscanner : public QObject +{ + Q_OBJECT +public: + tst_qtattributionsscanner(); + +private slots: + void test_data(); + void test(); + +private: + QString m_cmd; + QString m_basePath; +}; + + +tst_qtattributionsscanner::tst_qtattributionsscanner() +{ + QString binPath = QLibraryInfo::location(QLibraryInfo::BinariesPath); + m_cmd = binPath + QLatin1String("/qtattributionsscanner"); + m_basePath = QFINDTESTDATA("testdata"); +} + + +void tst_qtattributionsscanner::test_data() +{ + QTest::addColumn<QString>("directory"); + QTest::newRow("good") << QStringLiteral("good"); + QTest::newRow("warnings (incomplete)") << QStringLiteral("warnings/incomplete"); + QTest::newRow("warnings (unknown attribute)") << QStringLiteral("warnings/unknown"); +} + +static void readExpectedFile(const QString &dir, const QString &fileName, QByteArray *content) +{ + QFile file(QDir(dir).absoluteFilePath(fileName)); + QVERIFY2(file.open(QIODevice::ReadOnly | QIODevice::Text), "Could not open " + file.fileName().toLocal8Bit()); + *content = file.readAll(); + content->replace("%{PWD}", dir.toUtf8()); +} + +void tst_qtattributionsscanner::test() +{ + QFETCH(QString, directory); + + QString dir = QDir(m_basePath).absoluteFilePath(directory); + + QProcess proc; + QString command = m_cmd + " " + dir + " --output-format json"; + proc.start(command, QIODevice::ReadWrite | QIODevice::Text); + + QVERIFY2(proc.waitForStarted(), qPrintable(command + QLatin1String(" :") + proc.errorString())); + QVERIFY2(proc.waitForFinished(30000), qPrintable(command)); + + QVERIFY2(proc.exitStatus() == QProcess::NormalExit, + "\"qtattributionsscanner " + m_cmd.toLatin1() + "\" crashed"); + QVERIFY2(!proc.exitCode(), + "\"qtattributionsscanner " + m_cmd.toLatin1() + "\" exited with code " + + QByteArray::number(proc.exitCode())); + + { // compare error output + QByteArray stdErr = proc.readAllStandardError(); + stdErr.replace(QDir::separator(), "/"); + + QByteArray expectedErrorOutput; + readExpectedFile(dir, "expected.error", &expectedErrorOutput); + + QCOMPARE(stdErr, expectedErrorOutput); + } + + { // compare json output + QByteArray stdOut = proc.readAllStandardOutput(); + + QJsonParseError jsonError; + QJsonDocument actualJson = QJsonDocument::fromJson(stdOut, &jsonError); + QVERIFY2(!actualJson.isNull(), "Invalid output: " + jsonError.errorString().toLatin1()); + + QByteArray expectedOutput; + readExpectedFile(dir, "expected.json", &expectedOutput); + QJsonDocument expectedJson = QJsonDocument::fromJson(expectedOutput); + + if (!QTest::qCompare(actualJson, expectedJson, "actualJson", "expectedJson", __FILE__, __LINE__)) { + qWarning() << "Actual (actualJson) :" << actualJson; + qWarning() << "Expected (expectedJson):" << expectedJson; + return; + } + } +} + +QTEST_MAIN(tst_qtattributionsscanner) +#include "tst_qtattributionsscanner.moc" diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro new file mode 100644 index 000000000..51bd30734 --- /dev/null +++ b/tests/manual/manual.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS += \ + qtattributionsscanner diff --git a/tests/manual/qtattributionsscanner/data/LICENSE b/tests/manual/qtattributionsscanner/data/LICENSE new file mode 100644 index 000000000..0c0f8e15f --- /dev/null +++ b/tests/manual/qtattributionsscanner/data/LICENSE @@ -0,0 +1,686 @@ + GNU 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 GUI 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/tests/manual/qtattributionsscanner/data/qt_attribution.json b/tests/manual/qtattributionsscanner/data/qt_attribution.json new file mode 100644 index 000000000..d44985d35 --- /dev/null +++ b/tests/manual/qtattributionsscanner/data/qt_attribution.json @@ -0,0 +1,11 @@ +{ + "Id": "exampleattribution", + "Name": "Example Attribution", + "QDocModule": "somemodule", + "Description": "Does nothing specific.", + "QtUsage": "Optionally compiled into Some Qt Module. To avoid, pass \c -no-somemodule or \c -system-somemodule to \c configure.", + "License": "GNU General Public License v3.0 only", + "LicenseId": "GPL-3.0", + "LicenseFile": "LICENSE", + "Copyright": "Copyright (C) 2016 The Qt Company Ltd." +} diff --git a/tests/manual/qtattributionsscanner/overview.qdoc b/tests/manual/qtattributionsscanner/overview.qdoc new file mode 100644 index 000000000..716bb4e40 --- /dev/null +++ b/tests/manual/qtattributionsscanner/overview.qdoc @@ -0,0 +1,13 @@ +/*! + \page attributions.html + \title Credits + + \generatelist{annotatedattributions} +*/ + +/*! + \module SomeModule + \title Some Module + + \generatelist{groupsbymodule attributions-somemodule} + */ diff --git a/tests/manual/qtattributionsscanner/qtattributionsscanner.pro b/tests/manual/qtattributionsscanner/qtattributionsscanner.pro new file mode 100644 index 000000000..c3bcf99e3 --- /dev/null +++ b/tests/manual/qtattributionsscanner/qtattributionsscanner.pro @@ -0,0 +1,14 @@ +TEMPLATE = aux + +DISTFILES += test.qdocconf overview.qdoc data/qt_attribution.json data/LICENSE + +run_qtattributionsscanner.commands = $$[QT_HOST_BINS]/qtattributionsscanner \ + --filter QDocModule=somemodule -o generated.qdoc $$PWD + +run_docs.commands = BUILDDIR=$$OUT_PWD $$[QT_HOST_BINS]/qdoc $$PWD/test.qdocconf + +check.depends = run_qtattributionsscanner run_docs + +QMAKE_EXTRA_TARGETS += run_qtattributionsscanner run_docs check + +QMAKE_CLEAN += generated.qdoc diff --git a/tests/manual/qtattributionsscanner/test.qdocconf b/tests/manual/qtattributionsscanner/test.qdocconf new file mode 100644 index 000000000..46963495a --- /dev/null +++ b/tests/manual/qtattributionsscanner/test.qdocconf @@ -0,0 +1,6 @@ +project = Test + +outputdir = $BUILDDIR/html + +sourcedirs = $BUILDDIR . +sources.fileextensions = *.qdoc |